Spring 에서 Web Test 에 필요한 Annotation 비교

Spring 에서 Web Test 에 주로 사용되는 @SpringBootTest @AutoConfigureMockMvc @WebMvcTest 를 비교하고 정리해보자.

Spring 에서 Web Test 에 필요한 Annotation 비교

@SpringBootTest

SpringBootTest (Spring Boot 3.3.2 API)
declaration: package: org.springframework.boot.test.context, annotation type: SpringBootTest

특징

  • Application Context, Servlet container 를 모두 로드함.
    • 프로젝트 내부에 있는 모든 Spring bean 을 로드하고, 필요한 의존성이 추가됨.
  • 이러한 특징 때문에 외부 환경까지 동일할 경우 실제 환경과 같은 테스트를 수행할 수 있다.
  • 그러나 어플리케이션의 크기가 커질수록 context 를 로드하기 위한 시간이 오래 소요되며, 단위 테스트의 의미가 희석된다.
  • 단위 테스트에서보다는 Spring 전체를 돌리면서 프로그램이 정상적으로 동작하는지 확인하는 때에 확인하는 통합 테스트에서 주로 활용한다.

동작 과정

  • 아래는 TestContext 의 동작과정
../../_images/UsageOfLibraryForTestSpringTestProcessFlow.png

  • 테스트 코드를 실행하면, JUnit5 를 통해서 해당 테스트 코드가 실행된다.
  • TestContextManager 에 의해서 Spring Context 들이 로드된다. 이 때, 아래 언급한 MockMvc 를 호출하지 않는다면 Servlet Container 까지 함께 로드될 것이다.
  • 테스트 대상에 대해서 실제와 동등한 Spring bean 들이 DI 로 주입되며 (autowired) 테스트를 진행하고, 결과를 응답받는다.

@AutoConfigureMockMvc

AutoConfigureMockMvc (Spring Boot 3.3.2 API)
declaration: package: org.springframework.boot.test.autoconfigure.web.servlet, annotation type: AutoConfigureMockMvc
MockMvc (Spring Framework 6.1.11 API)
declaration: package: org.springframework.test.web.servlet, class: MockMvc
MockMvc :: Spring Framework

특징

  • AutoConfigureMockMvc@SpringBootTest 와 결합하여 사용한다. 따라서, 필요한 Spring bean 을 함께 로드하여 사용한다.
  • 그러나 다른 점이 있는데, @SpringBootTest 와 달리 실제 HTTP 요청을 수행하지 않는다는 점이다. MockMvc 를 통해서 HTTP 요청을 시뮬레이션할 수 있다.
    • 이 옵션을 사용하게되면 앞단의 웹서버가 작동하지 않는다. 즉, Servlet Container 가 작동하지 않는 것.
    • 이 덕택에 상대적으로 더 빠른 테스트가 가능해지며, 독립적인 환경에서 테스트할 수 있다.
  • Servlet 동작을 MockMvc 가 시뮬레이션하게 되며, Controller 에 제한된 동작을 검증할 수 있도록 돕는다.
    • 즉, 컨트롤러에 대한 단위 테스트를 하기 위한 도구이다.
  • MockMvc를 통해서 컨트롤러의 엔드포인트를 호출하고 요청을 모방하여 해당 요청에 대한 응답을 검증할 수 있다. 결과적으로 API End point 가 의도한 동작을 수행하는지 검증할 수 있다.
  • MockMvc → Servlet Container 의 동작을 Mocking → 가벼운 테스트, 의존성에서 분리된 테스트 → 테스트 대상에 집중하는 단위 테스트 실현
    • 그러나, AutoConfigureMockMvc + SpringBootTest 환경에서는 Spring bean 을 등록하고 사용한다. 따라서, 해당 목적을 완벽하게 달성하기는 어렵다. 통합 테스트에서 Servlet container 와의 분리의 목적으로 이해된다.

동작 과정

../../_images/UsageOfLibraryForTestMockMvcProcessFlow.png
  • 테스트 코드에서 MockMvc 를 통해서 Mock Request 를 요청하게 되면, Spring MVC 에서는 TestDispatcherServlet 을 통해 테스트하고자 하는 Controller 로 요청한다.
  • Controller 에서는 해당 코드를 실행하게되고 응답을 할 것이다.
  • 다시 테스트 코드에서는 해당 응답을 검증한다.

@WebMvcTest

WebMvcTest (Spring Boot 3.3.2 API)
declaration: package: org.springframework.boot.test.autoconfigure.web.servlet, annotation type: WebMvcTest

Annotation that can be used for a Spring MVC test that focuses only on Spring MVC components.

특징

  • @WebMvcTest 는 오직 Spring Mvc Component 에 집중할 수 있도록 한다.
  • 기존에 @SpringBootTest 에서 자동으로 모든 구성을 하던 것과 달리, 오직 MVC 테스트와 관련한 부분만 구성한다.
  • @WebMvcTest 는 특정 컨트롤러를 대상으로 테스트를 수행하도록 설정한다. 이 때, 해당 Controller 와 관련된 Bean 만 로드되며, @Component @Service @Repository 는 로드되지 않는다.
    • @Controller@ControllerAdvice@JsonComponentConverter/GenericConverterFilterWebMvcConfigurer and HandlerMethodArgumentResolver
    • @Component @Service @Repository 는 해당하지 않는다.
      • 서로 어떻게 다른 어노테이션인지 학습이 필요
    • 또한 Spring Security, MockMvc 또한 자동으로 구성한다.
    • @WebMvcTest(DMakerCOntroller.class)
  • MockMvc 를 사용하기에, 위에서 언급한 MockMvc 의 기능을 활용하여 Controller 영역에 대한 테스트를 환경에서 보다 더 격리하여 테스트할 수 있도록 한다.

결론

  • 모든 환경 / 의존성을 띄우고 통합 테스트 → @SpringBootTest
  • Servlet Container 를 환경에서 제외한 통합 테스트 → @SpringBootTest + @AutoConfigureMockMvc
  • HTTP 요청 처리 로직에 대한 부분적 통합 테스트 → @WebMvcTest (단위 테스트라고는 할 수 없음, 관련된 Bean 이 로드됨. 이 때, Filter, Interceptor 가 함께 로드됨)
  • MockMvc 의 역할 → Servlet Container 의 동작을 Mocking. 조금 더 단위테스트에 가까운 코드를 작성하도록 도움.
  • 완전한 Unit Test를 작성하고자 한다면 Mockito 를 사용해서 controller method 에 대해서 검증하려고하는 것도 가능할 것.
    • 그러나, 테스트 코드를 쓰다보면 서로 겹치는 부분이 많이 발생하곤하는데, 사실 이렇게 되면 테스트 코드에 대해서 상당히 스트레스를 유발할 수 있음. Controller 코드의 경우 E2E Test 정도로 충분하지 않을까 조심스레 생각…

참고

[Java] Spring Boot MockMvc 이해하기 : 테스트 흐름 및 사용예제
해당 글에서는 MockMvc에 대해 이해하고 활용하는 방법에 대해 확인해 봅니다. 💡 [참고] 이전에 작성한 Test 관련 글들을 읽으시면 도움이 됩니다.분류링크JUnit 5 이론 및 구성 요소https://adjh54.tistory.com/341JUnit 5 환경구성 및 활용예제https://adjh54.tistory.com/342JUnit 5 + Mockito 이론 및 활용예제https://adjh54.tistory.com/346JUnit 5 + MockMvc 이론 및 활용예제https://adjh54.tistory.com/347Assertions API Documenthttps://adjh54.tistory.com/348개발방법론 TDD, BDDhttps://adjh54.tistory.com/…
10.2.4. How to use OSS library used in unit test — TERASOLUNA Server Framework for Java (5.x) Development Guideline 5.4.1.RELEASE documentation

Unit Testing Principles, Practices, and Patterns

2.2. Overview of Spring MVC Architecture — TERASOLUNA Server Framework for Java (5.x) Development Guideline 5.4.1.RELEASE documentation
  • MVC 작동 과정에 대해서 가볍게 정리됨