Spring Boot 애플리케이션의 테스트를 수행할 때, 단독 클래스에서는 모든 테스트가 성공하였다. 그러나 전체 테스트를 실행하면 동일한 테스트 컨텍스트를 공유하면서
JPA Audit 기능이 의도치 않게 적용되는 문제가 발생하였다.
DirtiesContext나 ActiveProfile 등으로 해결을 시도하려했으나 효과가 없었다.
그래서 테스트 컨텍스트 자체를 분리하기로 했다.
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntityAbstract implements Serializable {
@Column(updatable = false, nullable = false)
@CreatedDate
private LocalDateTime createAt;
@Column(nullable = false)
@LastModifiedDate
private LocalDateTime updateAt;
}
@DataJpaTest
class MessageRepositoryTest {
@Test
public void 생성일_특정조건으로_메시지_검색() {
// given
MessageSearchDto searchDto =
Instancio.of(MessageSearchDto.class)
.set(field(MessageSearchDto::getStartAt), LocalDateTime.of(2025, 3, 20, 12, 0, 0))
.set(field(MessageSearchDto::getEndAt), LocalDateTime.of(2025, 3, 21, 12, 0, 0))
.create();
// when
PageRequest pageRequest = PageRequest.of(0, 10);
Page<MessageDto> result = messageRepository.findAllBySearchCondition(pageRequest, searchDto);
// then
assertThat(result.getContent()).hasSize(1);
}
}
그러나 모든 테스트를 전체 수행하면 @SpringBootTest 테스트의 컨텍스트가
엮이면서 Audit이 적용되어 내가 BeforeEach에서 생성한
2025-03-20T15:00:00 날짜인 데이터가 테스트를 실행하는 시점의
시간으로 Insert 되어서, 위의 테스트 케이스가 실패했다.
테스트 코드 패키지를 test/ 하위에 두 개의 최상위 패키지로 분리하였다.
test/java/com/hello/unit
test/java/com/hello/integration
이와 같이 패키지 구조를 분리함으로써, 전체 테스트 실행 시 서로 다른 테스트 컨텍스트를 사용하여 의도치 않은 Audit 기능 적용 문제를 방지하였다.
그리고 아래 코드를 build.gradle에 적용한다.
tasks.register('integrationTest', Test) {
useJUnitPlatform()
include '**/integration/**'
}
test {
useJUnitPlatform()
include '**/unit/**'
finalizedBy integrationTest
}
적용 후 ./gradlew build
를 실행해서 확인해보면
아래와 같이 test, integrationTest 2개의 task가 각각 별도로 실행되어
모든 테스트를 통과하는 것을 확인했다.
:check
로 변경하여./gradlew check
or ./gradlew build
를 수행해서