스프링 부트 테스트

Aiden Shin·2020년 2월 24일
0

Spring Boot 환경에서 Test 설정 및 실습을 해보자.

시작은 일단 spring-boot-starter-test를 추가하는 것 부터

Test 의존성 스코프로 추가

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>

@SpringBootTest@RunWith(SpringRunner.class)랑 같이 써야 함. 빈 설정 파일은 설정을 안해주나? 알아서 찾음. (@SpringBootApplication)

  • webEnvironment
    • MOCK: mock servlet environment. 내장 톰캣 구동 안 함.
      • 서블릿 구동한 것처럼 할 수 있는데 MOCK MVC 를 이용해야함
    • RANDON_PORT, DEFINED_PORT: 내장 톰캣 사용 함.
    • NONE: 서블릿 환경 제공 안 함.
  • @MockBean
    • ApplicationContext에 들어있는 빈을 Mock으로 만든 객체로 교체 함.
    • 모든 @Test 마다 자동으로 리셋.

MockMvc를 사용하여 테스트

    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
    @AutoConfigureMockMvc
    public class SamplecontrollerTest {
    
        //서버를 구동하지 않고 mockMvc를 사용하여 테스트
        @Autowired
        MockMvc mockMvc;
    
        @Test
        public void hello() throws Exception {
            mockMvc.perform(get("/hello"))
                .andExpect(status().isOk())
                .andExpect(content().string("hello ilhyun"))
                .andDo(print());
        }
    
    }

RANDOM_PORT와 @MockBean을 사용하여 controller test

    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    @AutoConfigureMockMvc
    public class SamplecontrollerTest {
    
        @Autowired
        TestRestTemplate testRestTemplate;
    
        //서비스는 목으로 대체하여 controller만 테스트
        @MockBean
        SampleService mockSampleService;
    
        @Test
        public void hello() {
    
            //controller만 테스트 하고싶다!! 서비스는 목으로 대체!! 이제 서비스는 shinilhyun을 리턴!
            when(mockSampleService.getName()).thenReturn("shinilhyun");
    
            String result = testRestTemplate.getForObject("/hello", String.class);
            assertThat(result).isEqualTo("hello shinilhyun");
        }
    
    }

WebTestClient 사용

  • 장점
    • async 이므로 기다리지 않아도 됨 (RestTamplate 는 sync)
    • api가 RestTamplate에 비해 쓰기 편함 (추천)

WebTestClient 의존성 추가

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

WebTestClient 사용 예

    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    @AutoConfigureMockMvc
    public class SamplecontrollerTest {
    
        //webTestClient 사용
        // async 이므로 기다리지 않아도 됨 (RestTamplate = sync)
        @Autowired
        WebTestClient webTestClient;
    
        @MockBean
        SampleService mockSampleService;
    
        @Test
        public void hello() {
            when(mockSampleService.getName()).thenReturn("shinilhyun");
            webTestClient.get().uri("/hello").exchange()
                .expectStatus().isOk()
                .expectBody(String.class).isEqualTo("hello shinilhyun");
        }
    
    }

슬라이스 테스트

레이어 별로 잘라서 테스트하고 싶을 때 (난 테스트 하고 싶은 것만 등록하고 싶다.)

  • @JsonTest
  • @WebMvcTest
  • @WebFluxTest
  • @DataJpaTest
  • ...

기타 테스트 유틸

  • OutputCapture
  • TestPropertyValues
  • TestRestTemplate
  • ConfigFileApplicationContextInitializer

OutputCaptur

로그를 비롯해서 콘솔에 찍이는 모든 것 (기록)검사 가능

OutputCapture 사용 예

    @RunWith(SpringRunner.class)
    @WebMvcTest(Samplecontroller.class)
    public class SamplecontrollerTest {
    
        @Rule
        public OutputCapture outputCapture = new OutputCapture();
    
        @MockBean
        SampleService mockSampleService;
    
        @Autowired
        MockMvc mockMvc;
    
        @Test
        public void hello() throws Exception {
    
            when(mockSampleService.getName()).thenReturn("shinilhyun");
    
            mockMvc.perform(get("/hello"))
                .andExpect(content().string("hello shinilhyun"));
    
            assertThat(outputCapture.toString())
                .contains("shinilhyun")
                .contains("skip");
        }
    
    }
profile
예전 블로그: https://shinilhyun.github.io/

0개의 댓글