본문으로 건너뛰기
Advertisement

16.4 @WebMvcTest@DataJpaTest 컨텍스트 슬라이싱

@SpringBootTest는 전체 애플리케이션 컨텍스트를 로드하여 속도가 매우 느립니다. **슬라이스 테스트(Slice Test)**는 필요한 레이어의 빈만 선별적으로 로드하여 테스트 속도를 크게 향상시킵니다.

1. @WebMvcTest — Controllers만 로드

서비스나 리포지토리 없이 Controller 레이어의 HTTP 요청/응답 로직만 검증합니다.

@WebMvcTest(UserController.class)  // UserController 관련 빈만 로드
class UserControllerTest {

@Autowired
private MockMvc mockMvc;

@MockBean // 스프링 컨텍스트에 Mock 빈을 등록 (@Mock과 다름!)
private UserService userService;

@Autowired
private ObjectMapper objectMapper;

@Test
@DisplayName("POST /api/users — 유효한 DTO이면 201 Created 응답")
void 회원_생성_201_응답() throws Exception {
// Given
CreateUserRequest request = new CreateUserRequest("홍길동", "hong@test.com");
UserDto createdUser = new UserDto(1L, "홍길동", "hong@test.com");
given(userService.createUser(any())).willReturn(createdUser);

// When & Then
mockMvc.perform(post("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.id").value(1L))
.andExpect(jsonPath("$.name").value("홍길동"))
.andDo(print()); // 요청/응답 상세 출력
}
}

2. @DataJpaTest — JPA 관련 빈만 로드

JPA 리포지토리, EntityManager만 올려서 쿼리 로직을 검증합니다. 기본적으로 인메모리 H2 DB를 기동합니다.

@DataJpaTest
@AutoConfigureTestDatabase(replace = Replace.NONE) // H2 대신 실제 DB(Testcontainers)를 쓰려면 이 설정 추가
class UserRepositoryTest {

@Autowired
private UserRepository userRepository;

@Autowired
private TestEntityManager entityManager;

@Test
@DisplayName("이메일로 사용자를 조회할 수 있다.")
void 이메일로_유저_조회() {
// Given: 테스트 데이터를 직접 영속화
entityManager.persist(new User("Alice", "alice@test.com"));
entityManager.flush();
entityManager.clear(); // 1차 캐시 비워서 실제 DB에서 조회하도록 강제

// When
Optional<User> result = userRepository.findByEmail("alice@test.com");

// Then
assertThat(result).isPresent();
assertThat(result.get().getName()).isEqualTo("Alice");
}
}
Advertisement