@WebMvcTest
- :스프링 MVC 컨트롤러가 의도한 대로 작동하는지 테스트 가능
- (실제 서버 환경이 아닌) 모의 웹 환경에서 스프링 애플리케이션 콘텍스트를 로드하고 스프링 MVC 인프라를 설정하며 @RestController 및 @RestControllerAdvice와 같은 MVC 계층에서 사용되는 빈만 포함
웹 MVC 슬라이스에 대한 통합 테스트
🔹 웹 MVC 슬라이스(Web MVC Slice)란?
Spring Boot의 @WebMvcTest를 사용하면 웹 계층(Web Layer)만 테스트할 수 있는 "슬라이스 테스트"를 수행할 수 있습니다.
📌 "슬라이스(Slice)"란?
- 전체 애플리케이션을 테스트하지 않고 특정 계층만 테스트하는 방식
- @WebMvcTest를 사용하면 Spring MVC(Web) 계층만 로드하고 나머지 Bean(예: Service, Repository)은 로드하지 않음
- 빠르고 가벼운 테스트 수행 가능
package com.polarbookshop.catalogservice.web;
import com.polarbookshop.catalogservice.BookController;
import com.polarbookshop.catalogservice.domain.BookNotFoundException;
import com.polarbookshop.catalogservice.domain.BookService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
// 수동 임포트
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
// 스프링 MVC 컴포넌트에 중점을 두고, 명시적으로는 BookController 클래스를 타깃으로하는 테스트 클래스임을 나타냄.
@WebMvcTest(BookController.class)
public class BookControllerMvcTests {
// 모의 환경에서 웹 계층을 테스트하기 위한 유틸리티 클래스
@Autowired
private MockMvc mockMvc;
// 스프링 3.4.0 버전부터는 @MockBean이 @MockitoBean으로 변경되었음
// 스프링 애플리케이션 콘텍스트에 BookService의 모의 객체를 추가.
@MockitoBean
private BookService bookService;
@Test
void whenGetBookNotExistingThenShouldReturn404() throws Exception {
String isbn = "73737319951";
given(bookService.viewBookDetails(isbn))
// 모의 빈이 어떻게 작동할지 규정
.willThrow(BookNotFoundException.class);
mockMvc
// MockMVC는 HTTP GET 요청을 수행하고 결과를 확인하기 위해 사용
.perform(get("/books/" + isbn))
// 응답이 "404 발견되지 않음" 상태를 가질 것으로 예상
.andExpect(status().isNotFound());
}
}
BookControllerMvcTests.java
gradlew.bat test --tests BookControllerMvcTests 로 테스트 실행.
소스를 만들다보면 자동 import가 안되는 애들이있다(여기에선 given, get, status). 항상 그러하듯 내가 설명을 쓸 주제는 안되서 챗지에게 맡겼다.
🔹 왜 import static 구문은 자동 임포트가 안될까?
import static 문은 일반적인 import 문과 다르게 정적(static) 메서드나 상수를 직접 참조할 때 사용돼요.
하지만 대부분의 IDE(예: IntelliJ, Eclipse)는 import static을 자동 임포트하지 않습니다.
📌 이유는?
1️⃣ 정적 메서드는 클래스 인스턴스를 통해 접근하는 것이 일반적이므로, 자동 임포트하면 코드 가독성이 떨어질 수 있음.
- 예를 들어, given(), get() 같은 메서드는 어떤 클래스의 정적 메서드인지 명확하지 않을 수 있음.
- 그래서 IDE가 자동으로 추가하지 않고, 개발자가 명확하게 선택하게끔 유도하는 거예요.
2️⃣ 일반 import와 다르게 import static은 명확한 컨텍스트 없이 사용하면 혼란을 줄 수 있음.
- 예를 들어, get() 메서드는 여러 라이브러리에서 동일한 이름으로 존재할 수 있어요.
- static import가 자동 추가되면 어떤 패키지에서 온 메서드인지 혼란스러울 수 있음.
3️⃣ 자동 임포트 시 충돌 가능성이 있음.
- 예를 들어, assertThat() 같은 메서드는 AssertJ와 JUnit에서 모두 제공되는데,
IDE가 자동으로 임포트하면 잘못된 패키지의 메서드가 임포트될 가능성이 있음.
'Java > Cloud Native Spring in Action' 카테고리의 다른 글
| 윈도우에 Grype(그라이프) 설치 (1) | 2025.02.17 |
|---|---|
| @JsonTest를 사용한 JSON 직렬화 테스트 (0) | 2025.02.10 |
| @SpringBootTest 를 통한 통합 테스트 (0) | 2025.02.10 |
| JUnit5를 이용한 단위 테스트 (1) | 2025.02.07 |
| 중앙식 예외 핸들러와 이를 이용한 오류 처리 (1) | 2025.02.06 |