Spring Boot 테스트 슬라이스: @WebMvcTest와 @DataJpaTest
@WebMvcTest로 컨트롤러를 격리하여 테스트하고 @DataJpaTest로 리포지터리 계층을 테스트합니다.
Spring Boot 테스트 슬라이스: @WebMvcTest와 @DataJpaTest은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Java Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
테스트 슬라이스란 무엇인가요?
테스트 슬라이스는 특정 계층에 해당하는 Spring 컨텍스트의 관련 부분만 로드합니다. 모든 항목을 로드하는 @SpringBootTest보다 빠르며 테스트 대상 계층을 격리합니다.
@WebMvcTest: 컨트롤러 계층만 테스트
@WebMvcTest(UserController.class)는 웹 계층만 로드합니다. 여기에는 컨트롤러, 필터, 보안 설정, Jackson이 포함됩니다. 서비스와 리포지토리는 @MockBean으로 모의 처리해야 합니다.
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired MockMvc mockMvc;
@MockBean UserService userService;
@Test
void get_user_returns_200() throws Exception {
given(userService.findById(1L)).willReturn(new UserDto(1L, "Alice"));
mockMvc.perform(get("/api/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("Alice"));
}
}MockMvc 요청 구성
MockMvcRequestBuilders로 요청을 구성합니다. POST/PUT 테스트에 사용할 헤더, 콘텐츠 유형, 요청 본문을 설정합니다.
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("""{"name":"Bob","email":"bob@example.com"}"""))
.andExpect(status().isCreated())
.andExpect(header().exists("Location"));@WebMvcTest에서 유효성 검사 테스트
유효하지 않은 요청 본문은 MethodArgumentNotValidException을 발생시킵니다. 400 상태 코드와 오류 응답 본문을 검증합니다.
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("""{"name":"","email":"bad"}"""))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.errors.name").exists());@DataJpaTest: 리포지토리 계층만 테스트
@DataJpaTest는 JPA 리포지토리, 내장 H2 데이터베이스, Hibernate, TestEntityManager를 로드합니다. 다른 빈(서비스, 웹 계층)은 로드하지 않습니다.
@DataJpaTest
class UserRepositoryTest {
@Autowired UserRepository repo;
@Autowired TestEntityManager em;
@Test
void find_by_email() {
em.persist(new User("Alice", "alice@example.com"));
em.flush();
Optional<User> found = repo.findByEmail("alice@example.com");
assertTrue(found.isPresent());
}
}TestEntityManager
TestEntityManager는 다음과 같은 편의 메서드를 제공하도록 EntityManager를 감쌉니다: persist(), flush(), find(), persistAndFlush().
User saved = em.persistAndFlush(new User("Bob", "bob@example.com"));
assertNotNull(saved.getId());
em.clear(); // detach all to force a real DB read
User fromDb = repo.findById(saved.getId()).orElseThrow();
assertEquals("Bob", fromDb.getName());@DataJpaTest 롤백
각 테스트는 기본적으로 트랜잭션에서 실행되며 테스트가 끝난 후 롤백됩니다. 테스트 간에 데이터가 유지되지 않으므로 수동으로 정리하지 않아도 테스트가 격리됩니다.
@DataJpaTest // each @Test is rolled back automatically
class OrderRepositoryTest {
@Test @Transactional
void count_orders_is_zero_by_default() {
assertEquals(0, orderRepo.count());
}
}@DataJpaTest에서 H2를 실제 데이터베이스로 교체
@AutoConfigureTestDatabase(replace = Replace.NONE)을 사용하면 H2 대신 application.properties에 구성된 실제 데이터베이스를 대상으로 @DataJpaTest를 실행할 수 있습니다.
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class ProductRepositoryTest {
// Uses the configured PostgreSQL, not H2
}@JsonTest: JSON 직렬화만 테스트
@JsonTest는 Jackson 구성을 로드합니다. JacksonTester를 사용하여 객체가 예상대로 직렬화 및 역직렬화되는지 검증합니다.
@JsonTest
class UserDtoJsonTest {
@Autowired JacksonTester<UserDto> json;
@Test
void serializes_correctly() throws Exception {
UserDto dto = new UserDto(1L, "Alice", "alice@example.com");
assertThat(json.write(dto)).hasJsonPathStringValue("$.email");
}
}@RestClientTest: REST 클라이언트 계층
@RestClientTest는 RestTemplate 또는 WebClient 기반 HTTP 클라이언트를 테스트합니다. HTTP 응답을 모의 처리하는 MockRestServiceServer를 구성합니다.
@RestClientTest(WeatherClient.class)
class WeatherClientTest {
@Autowired WeatherClient client;
@Autowired MockRestServiceServer server;
@Test
void fetches_weather() {
server.expect(requestTo("/api/weather")).andRespond(withSuccess("""{"temp":22}""", APPLICATION_JSON));
Weather w = client.getWeather("Istanbul");
assertEquals(22, w.getTemp());
}
}@Import로 슬라이스 결합
슬라이스는 설계상 많은 빈을 제외합니다. 슬라이스에 필요한 특정 구성 클래스를 추가하려면 @Import(SomeConfig.class)를 사용합니다.
@WebMvcTest(UserController.class)
@Import(SecurityConfig.class) // load security for auth tests
class SecuredControllerTest { ... }빠른 확인
@DataJpaTest는 기본 데이터베이스로 무엇을 사용하나요?
복습
@WebMvcTest는 MockMvc를 사용하여 컨트롤러 계층을 테스트하고, 서비스는 @MockBean으로 모의 처리합니다. @DataJpaTest는 TestEntityManager와 자동 롤백을 사용하여 리포지토리를 테스트합니다. 실제 데이터베이스에는 Replace.NONE을 사용합니다. 직렬화에는 @JsonTest, HTTP 클라이언트에는 @RestClientTest를 사용합니다.
자주 묻는 질문
“Spring Boot 테스트 슬라이스: @WebMvcTest와 @DataJpaTest” 강의는 무료인가요?
네 — “Spring Boot 테스트 슬라이스: @WebMvcTest와 @DataJpaTest” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“Spring Boot 테스트 슬라이스: @WebMvcTest와 @DataJpaTest”에서 뭘 배우나요?
@WebMvcTest로 컨트롤러를 격리하여 테스트하고 @DataJpaTest로 리포지터리 계층을 테스트합니다. 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Java Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“Spring Boot 테스트 슬라이스: @WebMvcTest와 @DataJpaTest” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- @CsvSource와 @MethodSource를 사용한 매개변수화 테스트
- Mockito 고급: 인수 캡처와 스파이
- Spring Boot 테스트 슬라이스: @WebMvcTest와 @DataJpaTest
- Testcontainers: 실제 데이터베이스 통합 테스트