Spring Boot는 @SpringBootTest 어노테이션을 통해 테스트에서 실제 애플리케이션 컨텍스트를 실행할 수 있는 강력한 기능을 제공한다. 이번 포스팅 에서는 아래 내용을 상세하게 설명하려고 한다.

  • @SpringBootTest의 역할과 사용 시점
  • 슬라이스 테스트(@WebMvcTest, @DataJpaTest, @DataJdbcTest 등)와의 비교
  • 컨텍스트 커스터마이징 방법
  • 테스트 시간을 어떻게 줄일 수 있는지

“테스트”란 무엇을 의미할까?

유닛 테스트(Unit Test)

  • 단일 클래스 또는 기능 단위를 테스트
  • 외부 의존성은 mock 처리
  • 빠르고 격리된 테스트
class UserServiceTest {
  @Test
  void testLogic() {
    // 단일 클래스 내 로직만 테스트
  }
}

통합 테스트(Integration Test)

여러 계층의 조합과 실제 흐름을 테스트

통합 테스트는 다음 중 하나일 수 있다:

  1. 여러 객체 간 상호작용 (예: 서비스 ↔ 레포지토리)
  2. 여러 계층 간 테스트 (컨트롤러 → 서비스 → DB)
  3. 전체 애플리케이션 플로우 (요청 → 응답 + 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슬라이스 테스트를 우선 고려
  • 컨텍스트 커스터마이징은 운영 환경과의 차이를 줄이는 선에서 최소화할 것

+ Recent posts