Spring Boot는 @SpringBootTest 어노테이션을 통해 테스트에서 실제 애플리케이션 컨텍스트를 실행할 수 있는 강력한 기능을 제공한다. 이번 포스팅 에서는 아래 내용을 상세하게 설명하려고 한다.
- @SpringBootTest의 역할과 사용 시점
- 슬라이스 테스트(@WebMvcTest, @DataJpaTest, @DataJdbcTest 등)와의 비교
- 컨텍스트 커스터마이징 방법
- 테스트 시간을 어떻게 줄일 수 있는지
“테스트”란 무엇을 의미할까?
유닛 테스트(Unit Test)
- 단일 클래스 또는 기능 단위를 테스트
- 외부 의존성은 mock 처리
- 빠르고 격리된 테스트
class UserServiceTest {
@Test
void testLogic() {
// 단일 클래스 내 로직만 테스트
}
}
통합 테스트(Integration Test)
여러 계층의 조합과 실제 흐름을 테스트
통합 테스트는 다음 중 하나일 수 있다:
- 여러 객체 간 상호작용 (예: 서비스 ↔ 레포지토리)
- 여러 계층 간 테스트 (컨트롤러 → 서비스 → DB)
- 전체 애플리케이션 플로우 (요청 → 응답 + DB 상태 확인)
@SpringBootTest
@AutoConfigureMockMvc
class RegisterUseCaseIntegrationTest {
@Autowired MockMvc mockMvc;
@Autowired UserRepository userRepository;
@Test
void registrationWorks() throws Exception {
mockMvc.perform(post("/register")
.contentType("application/json")
.content("{\"name\": \"jihun\"}"))
.andExpect(status().isOk());
assertTrue(userRepository.findByName("jihun").isPresent());
}
}
@SpringBootTest 란?
@SpringBootTest는 다음을 제공:
- 실제 운영 환경처럼 전체 컨텍스트를 로딩
- 컨트롤러, 서비스, 리포지토리, 빈 모두 포함
- 테스트 내에서 전체 요청/응답 흐름 시뮬레이션 가능
내부적으로
- @SpringBootConfiguration을 찾기 위해 패키지 상단까지 탐색
- 보통 @SpringBootApplication이 붙은 메인 클래스를 사용
다양한 슬라이스 테스트 어노테이션
Spring Boot는 특정 레이어만 테스트할 수 있도록 여러 "Test Slice" 어노테이션을 제공한다.
@WebMvcTest
- 컨트롤러 계층만 로딩
- @Controller, @ControllerAdvice, MockMvc만 포함
- 서비스, 레포지토리는 mock 필요
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired MockMvc mockMvc;
...
}
@WebFluxTest
- WebFlux 환경에서 사용하는 슬라이스 테스트
- WebTestClient로 WebFlux 컨트롤러 테스트
@DataJpaTest
- JPA 엔티티, Repository 테스트
- H2 등 임베디드 DB 자동 설정
- DB 쿼리, 매핑, 제약 조건 검증에 적합
@DataJpaTest
class UserRepositoryTest {
@Autowired UserRepository userRepository;
...
}
@DataJdbcTest
- Spring Data JDBC 사용 시 적합
- 복잡한 매핑보다는 단순한 SQL 기반 테스트에 유용
@JsonTest
- Jackson, Gson 직렬화/역직렬화 검증
- ObjectMapper, JacksonTester 자동 구성
@RestClientTest
- RestTemplate 기반 외부 API 호출 테스트 전용
- MockRestServiceServer로 응답 모킹 가능
@SpringBootTest 커스터마이징 방법
1. MockMvc 사용: @AutoConfigureMockMvc
@SpringBootTest
@AutoConfigureMockMvc
class MyTest {
@Autowired MockMvc mockMvc;
}
2. 특정 프로퍼티 설정
@SpringBootTest(properties = "feature.enabled=true")
class FeatureTest {
@Value("${feature.enabled}")
boolean enabled;
}
3. 프로필 지정
@SpringBootTest
@ActiveProfiles("test")
class ProfileTest {}
→ application-test.yml에서 설정된 값 자동 로딩
4. @TestPropertySource로 외부 파일 지정
@SpringBootTest
@TestPropertySource("classpath:test.properties")
class FilePropertyTest {}
5. @MockBean으로 빈 대체
@SpringBootTest
class MockTest {
@MockBean UserRepository userRepository; // 진짜 빈을 mock으로 대체
}
6. @Import로 외부 빈 등록
@SpringBootTest
@Import(Foo.class)
class ImportTest {}
고급: @TestConfiguration, @SpringBootTest(classes = ...)
운영 클래스가 아닌 테스트 전용 애플리케이션 클래스를 사용할 수도 있다:
@SpringBootTest(classes = CustomTestApplication.class)
class CustomAppTest {}
혹은 @EnableScheduling 같은 설정을 켜고 끄는 조건부 빈을 작성할 수 있다:
@Configuration
@EnableScheduling
@ConditionalOnProperty(name = "scheduling.enabled", havingValue = "true")
public class SchedulingConfig {}
→ 테스트에서는 이렇게 끄기:
@SpringBootTest(properties = "scheduling.enabled=false")
왜 통합 테스트는 느릴까?
- @SpringBootTest는 전체 컨텍스트를 매번 로딩 → 느림
- 여러 커스터마이징이 다르면 캐시되지 않음
- 가능하면 공통 설정 재사용이 테스트 속도 향상에 도움
참고: JUnit Insights로 테스트 시간 시각화 가능
결론
- @SpringBootTest는 전체 경로(Controller → Service → Repository) 를 테스트할 때 가장 강력함
- 단순 레이어 테스트라면 @WebMvcTest, @DataJpaTest 등 슬라이스 테스트를 우선 고려
- 컨텍스트 커스터마이징은 운영 환경과의 차이를 줄이는 선에서 최소화할 것
'Spring' 카테고리의 다른 글
| 로깅 - SLF4J, Logback, Log4j2 차이 (1) | 2025.06.18 |
|---|---|
| JPA에서 save()는 언제 의미가 있을까? – 더티 체킹과의 차이 (1) | 2025.06.17 |
| SpringBoot static 변수에 @value 사용 (0) | 2025.01.17 |
| JPA - SELECT 보다 UPDATE 쿼리가 먼저 나가는 경우 (flush, 변경감지) (0) | 2025.01.07 |