미션 예제 코드에 @DirtiesContext라는 어노테이션을 사용하던 중 정확하게 어떤 어노테이션인지 알고자 정리한다.
기본적으로, 스프링 테스트에서는 ApplicationContext를 캐싱하여, 기존의 Context를 재활용한다.
따라서 DB 작업이 수행된 테스트가 존재할 때, 테스트 간에 격리가 되지 않고 테스트 간에 영향을 받게 될 수도 있는 것이다.
이럴 때 사용할 수 있는 것이 바로 @DirtiesContext 어노테이션이다.
@DirtiesContext 너는 누구냐
@DirtiesContext는 테스트 실행 중, Spring ApplicationContext가 Dirty 상태가 된다면 컨텍스트를 닫아버리는 것을 말한다.
즉, 애플리케이션 컨텍스트가 더티로 표시되면 테스트 프레임워크의 캐시에서 제거되고 닫힌다.
이때 Dirty 상태라는 것은 테스트가 싱글톤 빈의 상태를 변경하는 등 어떤 방식으로든, Spring Application Context를 수정하거나 손상시켰다는 것을 의미한다.
다시 말해, @DirtiesContext는 이 Context가 더러워졌을 경우를 감지하여 새 Context를 생성해주는 것이다.
이 @DirtiesContext 는 MethodMode, ClassMode, HierarchyMode 즉, 각 메서드, 클래스, 계층 레벨로 설정할 수 있다.
옵션 살펴보기
@DirtiesContext의 옵션이 AFTER_EACH_TEST_METHOD로 되어있었는데, 한번 살펴보자.
AFTER_EACH_TEST_METHOD는 테스트 클래스 내의 매 테스트 메서드가 실행된 후 컨텍스트를 dirty한 상태로 만든다.
따라서 DB에 영향이 가더라도 새로 전체 어플리케이션 컨텍스트를 생성하기 때문에 다른 테스트 코드에는 영향이 가지 않는다.
👀 출력하여 확인해보기
실제로 DataSource가 새로 생성되는지 확인하기 위해 코드에 DataSource를 주입받아 각 테스트에서 사용되는 DataSource를 로그로 출력해보자.
@DirtiesContext를 사용하지 않는 경우에는 각 테스트가 모두 HikariDataSource (HikariPool-1)를 사용하고, ApplicationContext가 생성되지 않아 ApplicationContext 생성에 대한 로그가 찍히지 않는 것을 확인할 수 있다.
하지만 @DirtiesContext를 사용하게 되면 아래처럼 각기 다른 HikariDataSource가 사용되고 있다는 것을 확인할 수 있다.
@DirtiesContext 항상 좋을까?
하지만 @DirtiesContext은 매번 컨텍스트를 재생성하기 때문에 성능상으로 좋지 않을 수 있다.
따라서 애플리케이션 규모나, 테스트 상황에 맞게 격리환경을 구성하는 것이 좋다.
+)
위의 코드는 아니지만, Jpa를 사용한 테스트 코드에서 @SpringBootTest + @DirtiesContext(BEFORE_EACH_TEST_METHOD)를 사용했을 경우 3초 276초가 걸린다. @SpringBootTest + @Transactional이나 @DataJpaTest로 실행 시 7배정도가 줄어든 것을 확인할 수 있다.
통합 테스트에서는 물론 적용이 불가능한 경우도 있으니 그때그때 상황에 맞게 적절하게 성능을 개선해보자
'우아한테크코스 6기 > 2단계' 카테고리의 다른 글
[방탈출 사용자 예약] @Bean, @Component, 그리고 POJO (0) | 2024.05.14 |
---|---|
영속성 entity 와 domain entity 분리해보기 (0) | 2024.05.12 |
[방탈출 예약 관리] 템플릿 엔진과 @RestController (0) | 2024.05.12 |
[레벨2] 1주차 회고 (0) | 2024.04.27 |
@SpringBootTest의 RANDOM_PORT 옵션과 RestAssured 함께 사용하기 (0) | 2024.04.25 |