이론/Spring

[Spring Test] Spring TestContext Framework

6161990 2022. 2. 2. 13:59

Prolog

스프링 4독을 앞두고 있다. 3독까지 해보니까 레퍼런스 전체적으로 자주 나오는 몇가지 키워드가 있다는 걸 알게되었다. 그래서 많이 등장하는 키워드를 한번 다 적어보았다.

 

 

그리고 실제 테스트를 돌려보았다. 많이 보았던 키워드들이 정말 많이 등장했다. 뭔진 모르겠지만 내가 앞으로 레퍼런스를 읽을 때 도움이 되겠구나.

Spring factories

All above listeners have a specific responsibility in Spring integration tests execution. For example, DependencyInjectionTestExecutionListener provides support for dependency injection and initialization of test instances.

예를들면 테스트에서의 DependencyInjection 에 대한 부분에서 TestExecutionListener 라는 키워드가 나오고 DirtiesContext 에 대한 부분에서도 TestExecutionListener 라는 키워드가 나왔.다. 도대체 TestExecutionListener 라는 키워드가 뭔데? 근데 또 하필 가장 많이 등장하는 키워드 두 개 (TestContext, TestExecutionListener) 가 Spring TestContext Framework 에 속한다. 사실 여기서 이름만 보더라도 중요한 역할을 하는 애들이구나 눈치챌 수 있었다.

 

Today’s Study Topic

Spring TestContext Framework

Notes

📌 TestExecutionListener

TestExecutionListener defines a listener API for reacting to test execution events published by the TestContextManager with which the listener is registered.

📌 TestContextManager

TestContextManager is the main entry point into the Spring TestContext Framework.

  • getTestContext() 메서드가 호출되면 실행되는 스레드에 TestContext 생성
  • TestContextManager 는 내부적으로 TestExecutionListener 를 가져온다. List<TestExecutionListener> 에 하나씩 넣고, 테스트 클래스 실행 전과 후, 테스트 메소드 실행 전과 후, 등록된 리스너들을 관리한다. handleBeforeException를을 통해 exception도 핸들링 하는 것 같이 보인다.

 

 

📌 DefaultTestContext implements TestContext

TestContext encapsulates the context in which a test is executed, agnostic of the actual testing framework in use.

→ / TestClass / TestMethod .. 등 테스트에 관련된 모든 정보가 있다.

 

→ cacheAwareContextLoaderDelegate.loadContext 을 통해 ApplicationContext가 생성된다!

 

 

 

  1. 테스트를 실행하면 @Test 어노테이션은 클래스 어노테이션(@SpringBootTest)을 확인하고 테스트 프레임워크의 TestContextManager를 호출한다.
  2. TestContextManager 는 Test Pool을 전반적으로 관리하는 TestContext 를 띄우고 , 이 컨텍스트는 실제 ApplicationContext를 띄우기 위해 ContextLoader 에 위임한다.
  3. ApplicationContext가 완성되면, TestExecutionListener 가 JUnit 생명주기에 맞춰 트랜잭션도 관리하면서, 테스트를 실행하게 된다.

    📍  내가 알게된 것 !
    1. 테스트에서 스프링 빈을 사용하기 위해서는 ApplicationContext를 띄워야 한다. (→ 스프링 부트 설정을 통해 자동으로 Spring TestContext Framework를 사용하게 되어있다)
    2. 테스트 프레임워크는 TextContext안에 ApplicationContext가 만든다.
    3. 테스트 프레임워크를 이루는 핵심 요소는 TestContextManager, TestContext, TestExecutionListener 이다.
    4. Spring Test에서 어플리케이션 컨텍스트는 딱 한 개만 만들어지고 모든 테스트에서 공유해서 사용한다. 따라서 어플리케이션 컨텍스트의 구성이나 상태를 테스트 내에서 변경하지 않는 것이 원칙이다. 만약 변경해야 한다면 @DirtiesContext 어노테이션을 붙이면 어플리케이션 컨텍스트를 공유하지 않는다.

 

 

많은 TestExecutionListner 중에 한 가지만 살펴보자.

public class MockitoTestExecutionListener

스프링 테스트에서 사용되는 Mock 을 생성해주고 있다...!

 

Relevant Question

더보기

📌 Question 

  • TestExecutionListeners 는 모든 테스트에 적용되는 걸까?
  • 그럼 mock객체가 필요없는 테스트에 MockitoTestExecutionListener 가 돌아가나? 디폴트가 그렇게 되어있는걸까?
  • 스프링 테스트 동작원리에 숨어있는 일정한 패턴들은 뭐가있을까.
  • TestContextManager 내부에서 발견한 TestContextBootstrapper 는 어떤 역할을 하는 걸까.

 

+) TestContextManager 내부에서 발견한 TestContextBootstrapper ?

실제로 테스트를 실행하면, textcontextBootstrapper가 호출되고 이는 테스트 프레임워크를 쉽게 실행시켜준다.

TestContextBootstrapper는 TestContextManager에서 현재 테스트에 대한 TestExecutionListeners를 가져오고 관리하는 TestContext를 빌드하는 데 사용됩니다.

 

 

+) 관련있는 것 같은데 뭔지 모르겠는 SpringExtension

 

Relevant Reference