본문 바로가기

Spring/Spring Boot

(SpringBoot) 테스트

 

테스트 코드 작성

컨트롤러

@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());
    }
}

실행결과

https://otrodevym.tistory.com/entry/Spring%EC%97%90%EC%84%9C-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BC%80%EC%9D%B4%EC%8A%A4-TDD-%EC%9E%91%EC%84%B1%ED%95%98%EA%B8%B0

 

Spring의 TDD 특징 및 사용법 정리

좋은 개발자가 되는 첫 걸음으로 TDD(Test Driven Development:테스트 주고 개발)을 정리합니다. 정리 후 의도적으로 실습하는 연습을 할 예정입니다. 테스트 주도 개발의 목적과 목표 -목적 새로운 버그의 발생을..

otrodevym.tistory.com


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

 

Web on Reactive Stack

The original web framework included in the Spring Framework, Spring Web MVC, was purpose-built for the Servlet API and Servlet containers. The reactive-stack web framework, Spring WebFlux, was added later in version 5.0. It is fully non-blocking, supports

docs.spring.io

 

의존성 추가

<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

 

mike6321/Spring

Contribute to mike6321/Spring development by creating an account on GitHub.

github.com

 

'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