Spring Framework를 사용하여 테스트 프로그램 작성 방법

woom·2023년 2월 28일
0

Framework

목록 보기
16/20
post-thumbnail

🌼 text 프로그램 작성 순서

  • Spring Framework를 사용하여 테스트 프로그램을 작성하여 단위 프로그램(모듈)을 테스트 하는 방법

    • SpringMVC에서의 모듈 : DAO 클래스, Service 클래스, Controller 클래스의 메소드
  1. junit 라이브러리와 spring-test 라이브러리를 프로젝트에 빌드 처리 (메이븐 : pom.xml)

  2. 테스트 프로그램에서 사용될 로그 구현체의 환경설정파일 변경

    • [src/test/resources] 폴더의 log4j.xml 파일의 내용 수정
  3. [src/test/java] 폴더에 테스트 프로그램에 대한 클래스 작성

    • junit 라이브러리와 spring-test 라이브러리에서 scope 속성을 주석 처리해야 테스트 프로그램 관련 클래스 작성 가능
    • 테스트 프로그램 실행 후 주석 제거
  4. 테스트 프로그램(JUnit) 실행 (모듈 테스트)


📌 빌드 처리 (pom.xml)

  • junit lib와 spring-test lib(Spring Framework를 이용하여 테스트 프로그램 작성에 필요한 기능을 제공) 빌드 처리

  • scope 속성을 주석 처리해야 테스트 프로그램 관련 클래스 작성 가능


		<!-- Test -->
		<dependency>
		    <groupId>junit</groupId>
		    <artifactId>junit</artifactId>
		    <version>4.13.2</version>
		    <!-- <scope>test</scope> -->
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
		<!-- => Spring Framework를 이용하여 테스트 프로그램 작성에 필요한 기능을 제공하는 라이브러리 -->
		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-test</artifactId>
		    <version>${org.springframework-version}</version>
		    <!-- <scope>test</scope> -->
		</dependency>



📕 log4j.xml (로그 구현체)

  • jdbc.sqltiming : SQL 명령의 실행시간(ms) 기록

  • jdbc.audit : ResultSet 관련 매핑 정보를 제외한 모든 JDBC 관련 정보 기록

  • jdbc.resultsettable : ResultSet 관련 매핑 정보를 표(Table)형식으로 기록

  • jdbc.connection : Connection 객체 관련 정보 기록 (Open 또는 Close)



<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

	<!-- Appenders -->
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="Target" value="System.out" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%-5p: %c - %m%n" />
		</layout>
	</appender>
	
	<!-- Application Loggers -->
	<logger name="xyz.itwill.controller">
		<level value="info" />
	</logger>
	
	<!-- 3rdparty Loggers -->
	<logger name="org.springframework.core">
		<level value="info" />
	</logger>	
	
	<logger name="org.springframework.beans">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.context">
		<level value="info" />
	</logger>

	<logger name="org.springframework.web">
		<level value="info" />
	</logger>

<logger name="jdbc.sqlonly">
		<level value="info" />
	</logger>
	
	<!-- jdbc.sqltiming : SQL 명령의 실행시간(ms) 기록 -->
	<logger name="jdbc.sqltiming">
		<level value="info" />
	</logger>
	
	<!-- jdbc.audit : ResultSet 관련 매핑 정보를 제외한 모든 JDBC 관련 정보 기록 -->
	<logger name="jdbc.audit">
		<level value="info" />
	</logger>
	
	<!-- jdbc.resultsettable : ResultSet 관련 매핑 정보를 표(Table)형식으로 기록 -->
	<logger name="jdbc.resultsettable">
		<level value="info" />
	</logger>
	
	<!-- jdbc.connection : Connection 객체 관련 정보 기록 - Open 또는 Close -->
	<logger name="jdbc.connection">
		<level value="info" />
	</logger>

	<!-- Root Logger -->
	<root>
		<priority value="info" />
		<appender-ref ref="console" />
	</root>
	
</log4j:configuration>





📙 DataSourceTest

  • @RunWith : 테스트 프로그램의 클래스를 객체로 생성하여 테스트 메소드를 호출하기 위한 클래스를 설정하는 어노테이션

    • 테스트 클래스를 실행하기 위한 클래스 설정하는 어노테이션
    • value 속성 : 테스트 클래스을 실행하기 위한 클래스(Class 객체)를 속성값으로 설정
    • 다른 속성이 없는 경우 속성값만 설정 가능
    • SpringJUnit4ClassRunner 클래스를 사용하여 테스트 클래스를 실행할 경우 ApplicationContext 객체(Spring Container)가 생성되어 제공
    • @RunWith(SpringJUnit4ClassRunner.class)
  • @ContextConfiguration : 테스트 클래스에서 사용할 수 있는 Spring Bean를 제공하기 위한 Spring Bean Configuration File을 설정하는 어노테이션

    • 스프링 컨테이너에 의해 관리하기 위한 객체
    • locations 속성 : Spring Bean Configuration File의 경로를 요소로 저장한 배열을 속성값으로 설정
    • Spring Bean Configuration File의 경로는 file 접두사를 사용하여 파일 시스템 형식으로 표현
    • @ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/root-context.xml"})
  • 테스트 클래스의 메소드에서 사용할 객체를 저장하기 위한 필드 선언

    • @AutoWired 어노테이션을 필드에 사용하여 의존성 주입 (생성자를 이용한 의존성 주입 불가능)
  • @Test : 테스트 메소드를 설정하는 어노테이션

    • SpringJUnit4ClassRunner에 의해 호출되어 모듈 테스트를 실행할 메소드



package xyz.itwill.controller;

//@RunWith : 테스트 프로그램의 클래스를 객체로 생성하여 테스트 메소드를 호출하기 위한 클래스를
//설정하는 어노테이션 - 테스트 클래스를 실행하기 위한 클래스 설정하는 어노테이션
//value 속성 : 테스트 클래스을 실행하기 위한 클래스(Class 객체)를 속성값으로 설정
// => 다른 속성이 없는 경우 속성값만 설정 가능
//SpringJUnit4ClassRunner 클래스를 사용하여 테스트 클래스를 실행할 경우 ApplicationContext 
//객체(Spring Container)가 생성되어 제공
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration : 테스트 클래스에서 사용할 수 있는 Spring Bean를 제공하기 위한 Spring
//Bean Configuration File을 설정하는 어노테이션 - 스프링 컨테이너에 의해 관리하기 위한 객체 
//locations 속성 : Spring Bean Configuration File의 경로를 요소로 저장한 배열을 속성값으로 설정
// => Spring Bean Configuration File의 경로는 file 접두사를 사용하여 파일 시스템 형식으로 표현
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/root-context.xml"})
public class DataSourceTest {
	private static final Logger logger=LoggerFactory.getLogger(DataSourceTest.class);
	
	//테스트 클래스의 메소드에서 사용할 객체를 저장하기 위한 필드 선언
	// => @AutoWired 어노테이션을 필드에 사용하여 의존성 주입 - 생성자를 이용한 의존성 주입 불가능
	@Autowired
	private DataSource dataSource;
	
	//@Test : 테스트 메소드를 설정하는 어노테이션
	// => SpringJUnit4ClassRunner에 의해 호출되어 모듈 테스트를 실행할 메소드
	@Test
	public void testDataSource() throws SQLException {
		logger.info("DataSource = "+dataSource);
		Connection connection=dataSource.getConnection();
		logger.info("Connection = "+connection);
		connection.close();
	}
}





📒 ServiceTest

  • 테스트 클래스의 메소드에서는 일반적으로 Service 클래스의 메소드 또는 Controller 클래스의 메소드를 호출하여 메소드가 정상적으로 동작되는지를 검사할 목적으로 작성

  • @WebAppConfiguration : ApplicationContext 객체가 아닌 WebApplicationContext 객체로 스프링 컨테이너 역활을 제공하도록 설정하기 위한 어노테이션

  • @FixMethodOrder : 테스트 메소드의 호출순서를 설정하기 위한 어노테이션

    • value 속성 : MethodSorters 자료형(Enum)의 상수 중 하나를 속성값으로 설정
    • MethodSorters.DEFAULT : JUnit 프로그램의 내부 규칙에 의해 정렬되어 메소드 호출 (테스트마다 동일한 순서로 메소드 호출 - 실행해봐야 확인 가능)
    • MethodSorters.JVM : JVM에 의해 정렬되어 메소드 호출 (테스트마다 불규칙한 순서로 메소드 호출- random)
    • MethodSorters.NAME_ASCENDING : 테스트 메소드의 이름을 오름차순 정렬하여 메소드 호출
    • @FixMethodOrder(value = MethodSorters.NAME_ASCENDING)



package xyz.itwill.controller;

@RunWith(SpringJUnit4ClassRunner.class)
//@WebAppConfiguration : ApplicationContext 객체가 아닌 WebApplicationContext 객체로 스프링
//컨테이너 역활을 제공하도록 설정하기 위한 어노테이션
@WebAppConfiguration
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/root-context.xml"
		,"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
//@FixMethodOrder : 테스트 메소드의 호출순서를 설정하기 위한 어노테이션
//value 속성 : MethodSorters 자료형(Enum)의 상수 중 하나를 속성값으로 설정
// => MethodSorters.DEFAULT : JUnit 프로그램의 내부 규칙에 의해 정렬되어 메소드 호출 - 테스트마다 동일한 순서로 메소드 호출
// => MethodSorters.JVM : JVM에 의해 정렬되어 메소드 호출 - 테스트마다 변경된 순서로 메소드 호출
// => MethodSorters.NAME_ASCENDING : 테스트 메소드의 이름을 오름차순 정렬하여 메소드 호출
@FixMethodOrder(value = MethodSorters.NAME_ASCENDING)
public class StudentServiceTest {
	private static final Logger logger=LoggerFactory.getLogger(StudentServiceTest.class);

	@Autowired
	private StudentService studentService;
	
	@Test
	public void testAddStudent() {
		Student student=new Student();
		student.setNo(6000);
		student.setName("홍경래");
		student.setPhone("010-6781-4311");
		student.setAddress("서울시 중랑구");
		student.setBirthday("2000-09-10");
		
		studentService.addStudent(student);
	}
	
	@Test
	public void testGetStudentList() {
		List<Student> studentList=studentService.getStudentList();
		
		for(Student student:studentList) {
			//DTO 클래스의 toString() 메소드 호출 - 모든 필드값을 문자열로 변환하여 반환
			logger.info(student.toString());
		}
	}
}





📗 ControllerTest

  • [ * ] 패턴문자를 사용하여 Spring Bean Configuration File 설정 가능

    • [ ** ] 형식으로 0개 이상의 하위 폴더를 표현 가능
  • WebApplicationContext 객체를 저장하기 위한 필드 선언 (DI)

    • WebApplicationContext 객체 : SpringMVC 프로그램에서 스프링 컨테이너 역활을 제공하기 위한 객체
  • MockMvc 객체를 저장하기 위한 필드 선언

    • MockMvc 객체 : 요청과 응답을 가상으로 제공하기 위한 객체
  • @Before : 테스트 메소드 호출 전 실행될 명령을 작성한 메소드를 설정하는 어노테이션 (초기화 작성)

  • MockMvcBuilders.webAppContextSetup(WebApplicationContext context)

    • MockMvcBuilder 객체를 생성하여 반환하기 위한 메소드
    • mvc=MockMvcBuilders.webAppContextSetup(context).build();
  • MockMvc.perform(Builder requestBuilder) : 가상으로 페이지를 요청하는 메소드

    • Controller 클래스에서 해당 페이지의 요청 처리 메소드 호출
    • 요청에 대한 처리결과가 저장된 ResultActions 객체 반환
    • MockMvcRequestBuilders.get(String url) : URL 주소를 전달받아 GET 방식으로 요청하는 메소드
    • 페이지에 대한 URL 주소의 요청 관련 정보(리퀘스트 메세지)가 저장된 Builder 객체 반환
    • ResultActions.andReturn() : 요청 처리 메소드의 실행 결과를 MvcResult 객체로 반환하는 메소드
    • MvcResult result=mvc.perform(MockMvcRequestBuilders.get("/student/display")).andReturn();



package xyz.itwill.controller;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
//[*] 패턴문자를 사용하여 Spring Bean Configuration File 설정 가능
// => [**] 형식으로 0개 이상의 하위 폴더를 표현 가능
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/**/*.xml"})
public class StudentControllerTest {
	private static final Logger logger=LoggerFactory.getLogger(StudentControllerTest.class);

	//WebApplicationContext 객체를 저장하기 위한 필드 선언 - DI
	// => WebApplicationContext 객체 : SpringMVC 프로그램에서 스프링 컨테이너 역활을 제공하기 위한 객체
	@Autowired
	private WebApplicationContext context;
	
	//MockMvc 객체를 저장하기 위한 필드 선언
	// => MockMvc 객체 : 요청과 응답을 가상으로 제공하기 위한 객체
	private MockMvc mvc;
	
	//@Before : 테스트 메소드 호출 전 실행될 명령을 작성한 메소드를 설정하는 어노테이션 - 초기화 작성
	@Before
	public void setup() {
		//MockMvcBuilders.webAppContextSetup(WebApplicationContext context)
		// => MockMvcBuilder 객체를 생성하여 반환하기 위한 메소드
		//MockMvcBuilder.build() : MockMvc 객체를 생성하여 반환하기 위한 메소드
		mvc=MockMvcBuilders.webAppContextSetup(context).build();
		logger.info("MockMvc 객체 생성");
	}
	
	@Test
	public void testStudentDisplay() throws Exception {
		//MockMvc.perform(Builder requestBuilder) : 가상으로 페이지를 요청하는 메소드
		// => Controller 클래스에서 해당 페이지의 요청 처리 메소드 호출
		// => 요청에 대한 처리결과가 저장된 ResultActions 객체 반환
		//MockMvcRequestBuilders.get(String url) : URL 주소를 전달받아 GET 방식으로 요청하는 메소드
		// => 페이지에 대한 URL 주소의 요청 관련 정보(리퀘스트 메세지)가 저장된 Builder 객체 반환 
		//ResultActions.andReturn() : 요청 처리 메소드의 실행 결과를 MvcResult 객체로 반환하는 메소드
		MvcResult result=mvc.perform(MockMvcRequestBuilders.get("/student/display")).andReturn();
		
		logger.info(result.getModelAndView().getViewName());
		logger.info(result.getModelAndView().getModel().toString());
	}
	
}





profile
Study Log 📂

0개의 댓글