Spring에서 Junit을 통해 테스트하는데 익숙해져있다.
이 방식과 더불어서 Spring의 MockMvc를 이용하여 Web Layer를 테스트 하는 방법에 대해 공부해보자.
우선 테스트를 진행하기 위해서 Spring-boot-starter-test를 추가해야한다.
Gradle
1 | testCompile("org.springframework.boot:spring-boot-starter-test") | cs |
그러면 테스트 클래스 파일에 @SpringBootTest와 @RunWith가 추가된다.
@SpringBootTest는 Spring Boot에서 주 구성 클래스를 찾아서 Spring Application Context를 시작하도록 하는 어노테이션이다.
Controller 테스트를 진행할 떄 서버를 가동시키고 TestRestTemplate를 사용하여 테스트를 진행할 수 있다.
TestRestTemplate를 이용한 web layer 테스트
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class HttpRequestTest { @LocalServerPort private int port; @Autowired private TestRestTemplate restTemplate; @Test public void greetingShouldReturnDefaultMessage() throws Exception { assertThat(this.restTemplate.getForObject("http://localhost:" + port + "/", String.class)).contains("Hello World"); } } | cs |
하지만 서버 실행하고 테스트를 진행하면 너무 비용이 크기 때문에 이런 비용을 없에기 위해서 MockMvc를 사용할 수 있다.
MockMvc를 이용한 테스트
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @RunWith(SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc public class ApplicationTest { @Autowired private MockMvc mockMvc; @Test public void shouldReturnDefaultMessage() throws Exception { this.mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk()) .andExpect(content().string(containsString("Hello World"))); } } | cs |
하지만 위와같은 방식은 모든 Spring application의 context가 실행 되었기 때문에 단순히 web layer만을 사용하여 테스트 하고 싶은 경우에 @WebMvcTest 애노테이션을 설정하여 간단하게 테스트를 진행할 수 있다.
WebMvcTest 애노테이션을 이용한 테스트
1 2 3 4 5 6 7 8 9 10 11 12 13 | @RunWith(SpringRunner.class) @WebMvcTest public class WebLayerTest { @Autowired private MockMvc mockMvc; @Test public void shouldReturnDefaultMessage() throws Exception { this.mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk()) .andExpect(content().string(containsString("Hello World"))); } } | cs |
방식은 모두 같지만 모든 context를 로드하지 않고 web layer만 로드하기에 비용이 더저렴하다.
또한 컨트롤러에서 의존주입한 서비스는 @MockBean 어노테이션을 사용하여 inject 하여 사용할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @RunWith(SpringRunner.class) @WebMvcTest(GreetingController.class) public class WebMockTest { @Autowired private MockMvc mockMvc; @MockBean private GreetingService service; @Test public void greetingShouldReturnMessageFromService() throws Exception { when(service.greet()).thenReturn("Hello Mock"); this.mockMvc.perform(get("/greeting")).andDo(print()).andExpect(status().isOk()) .andExpect(content().string(containsString("Hello Mock"))); } } | cs |
위의 코드에 보면 GreetingService에 경우 GreetingController에서 주입되는 Bean이기 때문에 @MockBean 형태로 가지고와서 Mockito 형태로 사용할 수 있다.
Spring에서 단위 테스트를 할 수 있는 방식은 많다. 조금 더 비용을 줄이고 효율적으로 테스트 할 수 있는 방법을 알고 사용해보자!
'web > Spring' 카테고리의 다른 글
Spring boot hibernate jpa에서 Auditing 사용 - update, create 시간 자동 변경 (3) | 2018.10.03 |
---|---|
Spring Validation을 이용해서 요청 검증처리 (0) | 2018.08.09 |
Java 9 이후 deprecated된 Spring @PostConstruct와 @PreDestory 대안소개 (0) | 2018.08.07 |
Swagger 라이브러리를 사용하여 API 내용 정리하기 (0) | 2018.08.07 |
[Spring Boot] Maven에서 Gradle로 변경 후 발생한 FreeMarkerWebConfiguration NoSuchFieldError 수정 (0) | 2018.08.05 |