테스트 코드 작성
컨트롤러
@RestController
public class SampleController {
@Autowired
SampleService sampleService;
@GetMapping("/hello")
public String hello() {
return "hello"+sampleService.getName();
}
}
서비스
@Service
public class SampleService {
public String getName() {
return "junwoo";
}
}
테스트 코드
@ExtendWith({SpringExtension.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void hello() throws Exception {
mockMvc.perform(get("/hello"))
.andExpect(content().string("hellojunwoo"))
.andDo(print());
}
}
webEnvironment
- MOCK: mock servlet environment. 내장 톰캣 구동 안 함.
- WebEnvironment.MOCK : 서블릿 컨테이너를 테스트용으로 띄우지 않고 서블릿을 mocking 한 것이 뜬다.
- (MockMvc client가 필요)
@ExtendWith({SpringExtension.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
public class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void hello() throws Exception {
mockMvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string("hellojunwoo"))
.andDo(print());
}
}
MockHttpServletRequest:
HTTP Method = GET
Request URI = /hello
Parameters = {}
Headers = []
Body = null
Session Attrs = {}
Handler:
Type = me.choi.springtestdemo.SampleController
Method = me.choi.springtestdemo.SampleController#hello()
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = [Content-Type:"text/plain;charset=UTF-8", Content-Length:"11"]
Content type = text/plain;charset=UTF-8
Body = hellojunwoo
Forwarded URL = null
Redirected URL = null
Cookies = []
RANDON_PORT, DEFINED_PORT: 내장 톰캣 사용함
내장 톰캣 서버에 요청을 보내서 응답을 받은 것
@ExtendWith({SpringExtension.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SampleControllerTest {
@Autowired
TestRestTemplate testRestTemplate;
@Test
public void hello() throws Exception {
String result = testRestTemplate.getForObject("/hello", String.class);
assertEquals(result,"hellojunwoo");
}
}
Service까지 가지 않고 Controller만 한정해서 테스트를 하고 싶을 경우
@MockBean 사용
: MockBean을 하면 Application-Context의 빈을 테스트의 MockBean으로 교체한다.
그다음 해당 컨트롤러에 주입된 Service도 원본이 아닌 Mock으로 만들어준다.
@MockBean
SampleService mockSampleService;
@Test
public void hello() throws Exception {
when(mockSampleService.getName()).thenReturn("junwoo");
String result = testRestTemplate.getForObject("/hello", String.class);
assertEquals(result,"hellojunwoo");
}
WebTestClient의 사용(Java 5부터 추가)
Spring MVC Webflux의 RestClient 중 일부
- 기존의 restClient는 Synchronous 하다 - 요청을 보내면 요청이 끝날 때까지 기다려야 한다.
- webClient는 aSynchronous 하다 - 요청을 보내고 기다리는 것이 아닌 요청이 끝나면 callBack이 오는 형태이다.
https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html
의존성 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
@Test
public void hello() throws Exception {
when(mockSampleService.getName()).thenReturn("junwoo");
webTestClient.get().uri("/hello").exchange().expectStatus().isOk()
.expectBody(String.class).isEqualTo("hellojunwoo");
}
슬라이스 테스트
: 모든 Bean이 등록되는 것을 원하지 않고 내가 원하는 Bean만 등록하고 싶을 때 사용하는 방법
@WebMvcTest(SampleController.class)
해당 클래스만 테스트하기 때문에 클래스에 포함되어있던 모든 의존성이 끊기게 된다.
따라서 의존하는 Bean들은 모두 MockBean으로 등록되어야 한다.
@Test
public void hello() throws Exception {
when(mockSampleService.getName()).thenReturn("junwoo");
mockMvc.perform(get("/hello"))
.andExpect(content().string("hellojunwoo"));
}
@SpringBootTest : 큰 단위의 통합 테스트
코드 참조
https://github.com/mike6321/Spring/tree/master/SpringBoot/springtestdemo
'Spring > Spring Boot' 카테고리의 다른 글
(SpringBoot) Spring Mvc(1) (0) | 2020.01.10 |
---|---|
(SpringBoot) Spring-Boot-Devtools (0) | 2020.01.06 |
(SpringBoot) logging(2) - 커스터마이징 (0) | 2020.01.05 |
(SpringBoot) Logging (0) | 2020.01.05 |
(SpringBoot) 프로파일 (0) | 2020.01.05 |