일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- LiveTemplate
- 디자인패턴 #싱글톤
- 톰캣
- spring
- autocomplete
- Mockito #Reflection #Sigleton #Test #JUnit
- tomcat
- Spring Framework
- 외장톰캣
- Today
- Total
자라선
14. Test 본문
스프링 테스트 의존성 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
테스트 코드 기본 폼
@RunWith(SpringRunner.class)
@SpringBootTest
@SpringBootTest 어노테이션은 @SpringBootApplication 어노테이션을 찾아가 모든 자동설정을 실행하여
모든 bean 스캔과 테스트용 ApplicationContext에 등록한다.
MockMvc 사용 (통합 테스트)
3가지의 방법중 가장 쉬운 방법으로 서블릿 컨테이너를 생성하지 않고 디스패처 서블릿을 mocking 을 하여
비슷한 역할을 해준다. 그러나 mocking를 하여 생성된 디스패처 서블릿을 사용하려면 MockMvc 클라이언트를 사용해야한다.
@SpringBootTest에서 WebEnvironment의 값이 MOCK 이어야한다.(default = MOCK)
@AutoConfigureMockMvc 어노테이션을 작성하고 MockMvc를 주입받아 사용.
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
class SampleControllerTest {
@Autowired
MockMvc mockMvc;
@Test
void hello() throws Exception{
mockMvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string("hello taehyun"))
.andDo(print());
}
}
TestRestTemplate 를 사용 (통합 테스트)
MockMvc 와 다르게 @SpringBootTest의 webEnvironment 값을 RANDOM_PORT로 준다면 서블릿 컨테이너가 실행되며 이렇게 띄어진 톰캣에 직접 요청하여 테스트를 진행.
testRestTemplate의 getForObject를 통해서 Rest 리턴값을 받아 assertThat으로 확인
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class SampleControllerTest {
@Autowired
TestRestTemplate testRestTemplate;
@Test
void hello() throws Exception{
String result = testRestTemplate.getForObject("/hello", String.class);
assertThat(result).isEqualTo("hello taehyun");
}
}
특정 부분만 테스트를 하기 위해서는 @MockBean 어노테이션을 사용하여 ApplicationContext에 bean으로 등록된 동일 bean을 교체하여 테스트를 진행할 수 있다.
when() 를 사용해 조건을 준다. 아래같은 경우 service에서 getName 요청한다면 반환값을 "thkong"로 반환되도록 교체
import static org.mockito.Mockito.when;
…..
@MockBean
SamepleService mockSamepleService;
@Test
public void hello() throws Exception{
when(mockSamepleService.getName()).thenReturn("thkong");
비동기화 방식 테스트 (통합 테스트)
웹 플럭스를 사용하여 테스트를 진행 할 수 있다.
일반적인 테스트는 동기화 방식으로 요청 후 응답까지 기다려야하지만 웹 플럭스를 사용해 비동기 방식으로 한다면 요청 후 콜백이 돌아와 RestAPI의 테스트를 효율적으로 할 수 있다.
의존성 정의
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
코드
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.mockito.Mockito.when;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class SampleControllerTest {
@Autowired
WebTestClient webTestClient;
@MockBean
SamepleService mockSamepleService;
@Test
public void hello() throws Exception{
when(mockSamepleService.getName()).thenReturn("thkong");
webTestClient.get().uri("/hello").exchange().expectStatus().isOk()
.expectBody(String.class).isEqualTo("hello thkong");
}
}
슬라이스 테스트
통합 테스트 처럼 전체적으로 테스트 하지 않는다면 특정 부분만 정의하여 테스트를 진행할 수 있다.
· @JsonTest
· @WebMvcTest
· @WebFluxTest
· @DataJpaTest
특정 컨트롤러 만 테스트
@WebMvcTest 어노테이션을 정의하고 특정 컨트롤러의 클래스를 작성한 후
MockMvc 를 @Autowired로 bean을 주입받아서 사용해야한다.
하지만 @Component로 정의된 @Service나 @Repository 등의 어노테이션은 bean으로 생성되지 않기 때문에
@MockBean으로 특정 조건에 부합했을때의 결과값으로 정의해줘야한다.
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
@RunWith(SpringRunner.class)
@WebMvcTest(SampleController.class)
class SampleControllerTest {
@MockBean
SamepleService mockSamepleService;
@Autowired
MockMvc mockMvc;
@Test
public void hello() throws Exception{
when(mockSamepleService.getName()).thenReturn("thkong");
mockMvc.perform(get("/hello"))
.andExpect(content().string("hello thkong"))
.andDo(print());
}
}
@OutputCapture
System.out.println 이나 logger로 출력된 모든 콘솔 로그를 뽑아서 테스트 할 수 있다.
Junit 라이브러리의 @Rule를 사용한다.
@Rule
OutputCapture outputCapture;
assertThat(outputCapture.toString())
.contains("Controller Request")
.contains("Service Request");
'Develop > Spring Boot' 카테고리의 다른 글
16. Spring MVC (0) | 2020.07.27 |
---|---|
15. devtools (0) | 2020.07.27 |
13. Logging (0) | 2020.07.27 |
12. Profile (0) | 2020.07.27 |
11. 외부설정 (0) | 2020.07.27 |