JAVA/TEST
@SpringBootTest와 @WebMvcTest, @MockBean 그리고 WebClinet까지
gracelove91
2020. 1. 29. 22:07
코드
- 다음과 같은 컨트롤러와 서비스가 있다.
SampleController
@RestController
public class SampleController {
private SampleService sampleService;
public SampleController(SampleService sampleService) {
this.sampleService = sampleService;
}
@GetMapping("/hello")
public String hello() {
return "hello " + sampleService.getName();
}
}
SampleService
@Service
public class SampleService {
public String getName() {
return "gracelove";
}
}
localhost:8080/hello
로 요청을 보내면 "hello gracelove" 를 응답값으로 되돌려준다.
테스트
MockMvc를 이용한 테스트
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
디폴트값이다. 괄호 안에 옵션안주면 자동적용된다.
내장톰캣 실행안시킨다.
MockMvc 빈으로 등록 안시킨다
따라서 MockMvc를 이용하기 위해서는
@AutoConfigureMockMvc
가 필요하다@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) @AutoConfigureMockMvc class SampleControllerTest { @Autowired private MockMvc mockMvc; @Test void hello() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/hello")) .andExpect(status().isOk()) .andExpect(content().string("hello gracelove")) .andDo(print()); } }
TestRestTemplate 을 이용한 테스트
RANDOM_PORT
옵션주면 내장톰캣 실행한다.@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) class SampleControllerTest2 { @Autowired TestRestTemplate testRestTemplate; @Test void hello() { String result = testRestTemplate.getForObject("/hello", String.class); assertThat(result).isEqualTo("hello gracelove"); } }
WebTestClient를 이용한 테스트
non-blocking 기반의 클라이언트다.
이용하기 위해서는
pom.xml
에서 다음과 같이 의존성을 추가해주자.<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class SampleControllerTest3 {
@Autowired
WebTestClient webTestClient;
@Test
void hello() {
webTestClient.get().uri("/hello").exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("hello gracelove");
}
}
@WebMvcTest와 @MockBean을 이용한 테스트
위 테스트코드들은 모두 통합테스트다. 기본적으로
@SpringBootTest
어노테이션을 사용하면 스프링이 관리하는 모든 빈을 등록시켜서 테스트하기 때문에 무겁다.하지만
@WebMvcTest
는 web 레이어 관련 빈들만 등록하므로 비교적 가볍다.web레이어 관련 빈들만 등록되므로 Service는 등록되지않는다. 따라서 가짜로 만들어줄 필요가 있다 (@MockBean)
@WebMvcTest(SampleController.class) class SampleControllerTest4 { @Autowired MockMvc mockMvc; @MockBean SampleService mockSampleService; @Test void hello() throws Exception { when(mockSampleService.getName()).thenReturn("gracelove"); mockMvc.perform(MockMvcRequestBuilders.get("/hello")) .andDo(print()) .andExpect(status().isOk()) .andExpect(content().string("hello gracelove")); } }