2025. 3. 10. 23:54ㆍDev/TestCode

📝 어떤 프로젝트를 맡게 되어 개발을 하게 될 때 테스트 코드를 잘 작성하게 된다면, 운영 환경에서 겪게 될 문제점들 중 많은 부분들을 사전에 방지할 수 있습니다. Spring Boot 프레임워크를 이용한 개발 환경에서, 문득 @SpringBootTest와 @WebMvcTest의 차이점이 궁금하여 글을 작성하게 되었습니다.
MoctMvc
Spring Boot 프레임워크와 Junit을 이용하여 테스트 코드를 작성할 때, MoctMvc를 이용할 수 있습니다. 여기서 MockMvc는 스프링에서 제공해주는 테스트용 라이브러리입니다!
Spring 문서에서는 MoctMvc의 목표를 다음과 같이 소개하고 있는데요
MockMvc aims to provide more complete testing support for Spring MVC controllers without a running server.
...
MockMvc is a server-side test framework
that lets you verify most of the functionality of a Spring MVC application using lightweight and targeted tests.
서버를 running 하지 않고도 Spring MVC controllers를 지원하기 위한 testing 방법이라고 소개하고 있습니다.
MockMvc 객체를 주입받아 테스트를 진행할 수 있는데요!! 아래와 같은 메서드를 이용하게 됩니다.
| andExpect() | 실행된 결과를 확인하고 싶을 때 |
| andDo() | 일반적인 action을 수행했을 때 |
| andReturn() | 결과를 다루기 위해 실행 결과를 return 받을 때 |
@WebMvcTest
컨트롤러 계층을 test 할 수 있는 애노테이션으로, 컨트롤러만을 이용하기에 테스트 속도가 빠르다는 장점이 있습니다.
@WebMvcTest(ExceptionTest.TestController.class)
@Import(ExceptionTest.TestConfig.class)
public class ExceptionTest {
//이하 생략
다만, Contoller 을 테스트하기에.. Service나 Repository를 test하기 위해서는 @MockBean을 이용해야 합니다.
@SpringBootTest + @AutoConfigureMockMvc
위에서 언급한 @WebMvcTest처럼 Test할 때 사용되는 애노테이션입니다. 하지만 웹 애플리케이션 전체를 대상을 test하기에, 전체 bean을 불러오게 됩니다. @Service, @Repository 를 사용하는 객체들도 이용하게 되는데요! 따라서 @WebMvcTest보다 상대적으로 테스트 속도가 느리다는 단점이 있습니다.
@SpringBootTest
@AutoConfigureMockMvc
@Import(ExceptionTest.TestConfig.class)
public class ExceptionTest {
//이하 생략
| @WebMvcTest | @SpringBootTest + @AutoConfigureMockMvC |
| 웹 애플리케이션 전체 (예: Controller, Service, Repository) | Controller 단 |
| 느린 속도 | 빠른 속도 |
| MockBean X | MockBean O |
참고 예제 (static class를 이용하여 test 코드를 작성해봤습니다~!
일반 코드(200 return)와 에러 발생(exception) 코드를 호출하는 controller test입니다.
@Import(ExceptionTest.TestConfig.class)
public class ExceptionTest {
@Autowired
private MockMvc mockMvc;
@Test
void testHelloEndpoint() throws Exception {
mockMvc.perform(get("/test"))
.andExpect(status().isOk())
.andExpect(content().string("ok"));
}
@Test
void testCustomExceptionHandling() throws Exception {
mockMvc.perform(get("/error"))
.andExpect(status().isBadRequest())
.andExpect(content().string("exception occurred"));
}
@TestConfiguration
static class TestConfig {
@Bean
public TestController testController() {
return new TestController();
}
@Bean
public TestExceptionHandler testExceptionHandler() {
return new TestExceptionHandler();
}
}
@RestController
static class TestController {
@GetMapping("/test")
public ResponseEntity<String> hello() {
return ResponseEntity.ok("ok");
}
@GetMapping("/error")
public ResponseEntity<String> error() {
throw new CustomException("exception occurred");
}
}
@RestControllerAdvice
static class TestExceptionHandler {
@ExceptionHandler(CustomException.class)
public ResponseEntity<String> handleCustomException(CustomException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}
}
static class CustomException extends RuntimeException {
public CustomException(String message) {
super(message);
}
}
}
References
1. [Java] Spring Boot MockMvc 이해하기 : 테스트 흐름 및 사용예제
2. @WebMvcTest에 대한 올바른 사용법 및 시행착오
'Dev > TestCode' 카테고리의 다른 글
| [TestCode/Spring] TestCode에 Lombok 사용하기 (0) | 2024.03.10 |
|---|---|
| [TestCode/Spring] RANDOM_PORT (1) | 2024.03.09 |
| [TestCode/IntelliJ] show passed / test coverage (0) | 2024.03.09 |
| [TestCode] JUnit Test (0) | 2023.09.13 |