임대일
Spring Boot Junit5 이해하기: @WebMvcTest, @SpringBootTest 본문
Spring Boot Junit5 이해하기: @WebMvcTest, @SpringBootTest
스프링 부트에서 Junit 라이브러리로 테스트 코드를 작성할 때 @WebMvcTest, @SpringBootTest 어노테이션 두 가지를 가장 많이 사용합니다. 이번 장에서는 @WebMvcTest, @SpringBootTest 두 어노테이션의 차이점에 대해 학습합니다.
1. Mock, MockMvc
Mock
실제 객체를 만들기엔 비용과 시간이 많이 들거나 의존성이 길게 걸쳐져 있어 제대로 구현하기 어려울 경우, 가짜 객체를 만들어 사용하는데 이것을 Mock 이라 한다. 따라서 Mock 은 테스트할 때 필요한 실제 객체와 동일한 모의 객체를 만들어 테스트의 효용성을 높이기 위해 사용한다.
MockMvc
MVC에 관련된 Mock 객체를 말한다. MockMvc는 웹 어플리케이션을 애플리케이션 서버에 배포하지 않고 테스트 MVC 환경을 만들어 요청 및 전송, 응답 기능을 제공해주는 유틸리티 클래스이다. 웹 애플리케이션의 컨트롤러 및 RESTful 엔드포인트를 테스트할 때 실제 HTTP 요청을 보내지 않고도 테스트할 수 있다. 대신에 가짜 HTTP 요청을 만들고 해당 요청에 대한 응답 검증을 수행한다.
쉽게 정리해서 설명하자면, Mock 은 실제 객체가 아닌 테스트 전용 객체이고 MockMvc 는 MVC에 관련된 Mock 객체로서 컨트롤러와 관련된 테스트를 수행하기 위한 객체이다.
2. Mock 주입 시 차이
@WebMvcTest, @SpringBootTest 각각 적용된 테스트 코드마다 MockMvc 를 @Autowired 로 주입하는 방식에 차이가 있다. 또한 빈으로 등록되는 범위에도 차이가 있습니다. 먼저 Mock 주입 시 차이점에 대해 학습한다.
@SpringBootTest
@SpringBootTest class SpringBootTest { @Autowired MockMvc mockMvc; // 주입 X }
@SpringBootTest 가 선언된 테스트 코드에 MockMvc 를 @Autowired 로 주입하기 위해 위의 코드처럼 작성하면 주입이 되지 않고 에러가 발생한다. 그 이유는 @SpringBootTest 가 MockMvc 를 빈으로 등록시키지 않기 때문이다. 따라서 MockMvc 를 빈으로 등록하기 위해 @AutoConfigureMockmvc 어노테이션을 추가로 작성해야 한다.
@AutoConfigureMockMvc 추가
@SpringBootTest @AutoConfigureMockMvc // @AutoConfigureMockmvc 어노테이션을 추가 class SpringBootTest { @Autowired MockMvc mockMvc; // 주입 O }
따라서 @SpringBootTest 와 함께 @AutoConfigureMockMvc 를 작성해야 MockMvc 객체를 사용할 수 있다.
@WebMvcTest
@WebMvcTest class SpringBootTest { @Autowired MockMvc mockMvc; // 주입 O }
@WebMvcTest 는 MockMvc 를 빈으로 등록한다. 따라서 위의 코드처럼 @MvcMvcTest 작성된 테스트 코드는 MockMvc 를 @Autowired 로 객체가 주입된다.
3. 빈 등록 범위 차이
@SpringBootTest
@SpringBootTest @AutoConfigureMockMvc class SpringBootTest { @Autowired MockMvc mockMvc; // mockMvc 주입 O @Autowired UserController userController; // Controller 주입 O @Autowired UserRepository userRepository; // Repository 주입 O @Autowired UserService userService; // Service 주입 O }
@SpringBootTest 는 프로젝트의 컨트롤러, 리포지토리, 서비스 모두 @Autowired 으로 주입이 가능하다.
@WebMvcTest
@WebMvcTest class SpringBootTest { @Autowired MockMvc mockMvc; // MockMvc 주입 O @Autowired UserController userController; // Controller 주입 O @Autowired UserRepository userRepository; // Repository 주입 X @Autowired UserService userService; // Service 주입 X }
@WebMvcTest 는 Web Layer 와 관련된 빈을 등록한다. 따라서 컨트롤러만 정상적으로 주입하고, @Component 로 등록된 리포지토리와 서비스는 주입되지 않는다. @WebMvcTest 가 작성된 테스트 코드에서 리포지토리와 서비스를 주입하기 위해 @MockBean 을 사용하여 Mock 객체에 빈으로 등록해야 한다.
Web Layer 에 속한 항목
Security, Filter, Interceptor, request/response Handling, Controller
@MockBean 추가
@WebMvcTest class SpringBootTest { @Autowired MockMvc mockMvc; // MockMvc 주입 O @Autowired UserController userController; // Controller 주입 O @MockBean UserRepository userRepository; // Repository 주입 O -> @MockBean @MockBean UserService userService; // Service 주입 O -> @MockBean }
4. @SpringBootTest, @WebMvcTest 차이 정리
@SpringBootTest 사용
- MockMvc 객체를 빈으로 등록하지 않기 때문에
@AutoConfigureMockMvc
로 빈으로 등록해야 한다. - 프로젝트에 있는 스프링 빈을 모두 등록해서 테스트에 필요한 의존성을 추가해준다.
- MockMvc 객체를 빈으로 등록하지 않기 때문에
@SpringBootTest 장점
- 프로젝트에 있는 모든 스프링 빈을 등록하므로, 테스트에 필요한 객체를 주입받아서 쉽게 사용 가능하다.
- 실제 환경과 가장 유사하게 테스트가 가능하다.
@SpringBootTest 단점
- 모든 스프링 빈을 등록할 때 프로젝트의 전체 컨텍스트를 로드해서 빈을 주입하기 때문에 속도가 느리다.
- 테스트 단위가 크기 때문에 디버깅이 어려울 수 있다.
💡 단위 테스트와 같은 기능 테스트가 아닌, 전체적인 프로그램 작동이 제대로 이루어 지는지 검증하는 통합 테스트 시에 많이 사용한다!
@WebMvcTest 사용
- MockMvc 객체를 빈으로 등록해서
@Autowired
로 MockMvc 주입이 가능하다. - Web Layer 관련 빈들만 등록하기 때문에,
@Component
로 등록된 빈은@MockBean
으로 주입해야 한다.
- MockMvc 객체를 빈으로 등록해서
@WebMvcTest 장점
- Web Layer 관련 빈만 로드하기 때문에, 속도가 @SpringBootTest보다 빠르다.
- 통합테스트에서 테스트가 어려운 작은 단위 테스트들을 @WebMvcTest로 진행할 수 있다.
@WebMvcTest 단점
- Mock 객체를 사용하기 때문에 실제 환경에서는 다른 오류가 발생할 수 있다.
💡 이러한 이유로, 컨트롤러 테스트, 단위 테스트 시에 많이 사용한다!
'스프링' 카테고리의 다른 글
[Spring] Spring Boot 멀티 모듈 어플리케이션 설정: Gradle, DDD (1) | 2024.04.28 |
---|