@SpringBootTest 는 어떻게 동작할까? (1)

정원식·2024년 12월 25일

Spring Test

목록 보기
1/4

개요

  • 본 시리즈에서는 @SpringBootTest 의 동작 원리를 확인합니다
  • 첫번째 편에서는 기본 컴포넌트에 대해 알아봅니다.

사용한 버전

  • junit-jupiter: 5.10.3
  • spring-boot-test: 3.3.4
  • spring-test: 6.1.13

SpringExtension

  • 생각해보면 JUnit 테스트를 실행할뿐인데 Spring Application 이 구동이 됩니다. 어떻게 구동이 되는걸까요?
  • 테스트가 실행될때, org.springframework.test.context.junit.jupiter.SpringExtension 가 단계마다 호출되면서 TestContextManager 를 호출합니다. (JUnit Jupiter 기준)
  • TestContextManager 는 ApplicationContext 의 로딩을 담당합니다. (내부적으로 위임 처리)

  1. JUnit 에서 SpringExtension#beforeTestClass 호출 (테스트 클래스마다 호출)
  2. JUnit 에서 SpringExtension#postProcessTestInstance 호출 (모든 테스트마다 호출)
  3. JUnit 에서 SpringExtension#beforeEach 호출 (모든 테스트마다 호출)
  4. JUnit 에서 SpringExtension#beforeTestExecution 호출 (모든 테스트마다 호출)
  5. 테스트 실행
  6. JUnit 에서 SpringExtension#afterTestExecution 호출 (모든 테스트마다 호출)
  7. JUnit 에서 SpringExtension#afterEach 호출 (모든 테스트마다 호출)
  8. JUnit 에서 SpringExtension#afterAll 호출 (테스트 클래스마다 호출)
  9. 애플리케이션 종료는 java.lang.Runtime#addShutdownHook 을 통해 종료 처리

TestContext \& TestContextManager \& TestExecutionListener

  • TestContextManager
    • SpringExtension 에 의해 테스트마다 하나씩 생성됩니다.
    • TestContextBootstrapper 에게 TestContext 생성을 위임합니다.
    • TestContext 에게 ApplicationContext 생성을 위임합니다.
    • beforeEach, afterEach 와 같은 LifeCycle Callback 발생시, TestExecutionListener 에게 처리를 위임합니다.
  • TestContext
    • CacheAwareContextLoaderDelegate 에게 ApplicationContext 생성을 위임합니다.
    • CacheAwareContextLoaderDelegate 는 캐싱된 ApplicationContext 가 있으면 해당 컨텍스트를 반환합니다.
      • 다양한 요소를 키로 하여 ApplicationContext 를 캐싱합니다.
      • 캐싱된 ApplicationContext 가 없다면 SmartContextLoader 에게 위임합니다.
  • TestExecutionListener
    • LifeCycle Callback 발생시, TestContextManager 에 의해 호출됩니다.
    • 대표적인 TestExecutionListener 는 아래와 같습니다. TestExecutionListener Configuration
      • DependencyInjectionTestExecutionListener : 테스트 인스턴스에 DI 를 처리합니다 (@Autowired)
      • DirtiesContextTestExecutionListener : @DirtiesContext 를 처리합니다.
      • TransactionalTestExecutionListener : @Transactional 을 처리합니다.
    • SpringBootTest 를 실행한다고 했을때, 등록되는 TestExecutionListener 는 아래와 같습니다.

결론

  • JUnit 테스트 실행시 SpringExtension 을 통해 애플리케이션이 구동됨을 알아보았습니다.
  • 기본 컴포넌트 간의 관계에 대해 알아보면서 어떻게 애플리케이션이 초기화 되고 @Transactional 같은 어노테이션이 동작하는지 알아보았습니다.
  • 그러나 Spring Test 와 Spring Boot Test 는 초기화시 구체적인 단계가 다른데요, 이부분은 다음 편에서 알아보겠습니다~

Reference

profile
매일매일 성장하고 싶은 백엔드 개발자입니다.

0개의 댓글