이전 게시글(https://codestreet.tistory.com/93)에서 JpaConfig 클래스 안에 AuditorAware 빈을 생성 -> 랜덤 숫자를 리턴하게 하여 테스트 한 후 다시 운영 코드로 변경하였다.
문제는 이후 테스트를 할 때 마다 테스트용 코드로 바꿨다가 다시 운영용 코드로 바꿔야 해서 번거로웠다는 점이다.
AuditorAware에서는 리퀘스트 헤더에서 엑세스 토큰을 추출해 내고 그 안의 사용자ID값을 뽑아내어 CreatedBy 또는 LastModifiedBy의 값으로 지정한다. 단위 테스트 시에는 리퀘스트 헤더에 접근이 불가능하기 때문에 아래와 같이 HttpServletRequest를 정의할 수 없다고 뜬다.
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.tlog.backend.global.config.JpaConfig required a bean of type 'javax.servlet.http.HttpServletRequest' that could not be found.
Action:
Consider defining a bean of type 'javax.servlet.http.HttpServletRequest' in your configuration.
2024-10-15 11:12:36.589 ERROR 11836 --- [ main] o.s.test.context.TestContextManager : Caught exception while allowing TestExecutionListener [org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@8c3619e] to prepare test instance [com.tlog.backend.post.PostRepositoryTest@2dcd168a]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:98) ~[spring-test-5.3.31.jar:5.3.31]
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124) ~[spring-test-5.3.31.jar:5.3.31]
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118) ~[spring-test-5.3.31.jar:5.3.31]
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) ~[spring-test-5.3.31.jar:5.3.31]
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:43) ~[spring-boot-test-autoconfigure-2.7.18.jar:2.7.18]
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248) ~[spring-test-5.3.31.jar:5.3.31]
그래서 테스트용 JpaConfig를 별도로 생성하였다.
1. TestJpaConfig.java생성
우선 src/test/java 경로에 테스트 용 jpaConfig 클래스를 생성한다. src/main/java와 똑같은 패키지 구조로 생성했다.
2. AuditorAware 구현
이후 원래의 JpaConfig와 동일하게 @Configure, @EnableJpaAuditing 어노테이션을 추가하고 AuditorAware 빈을 생성해준다. 이전과 다른 점은 auditorAwareRef를 추가한다는 점이다. auditorAwareRef는 어떤 빈을 참조할 지 지정하는 역할을 수행한다. AuditorAware 빈이 운영 용과 테스트 용 두가지로 사용되므로 구분할 수 있도록 지정해주자.
그리고 @Profile("test")를 추가하여 테스트 시에만 인식되도록 하자.
@Configuration
@Profile("test")
@EnableJpaAuditing(auditorAwareRef = "testAuditorAware")
public class TestJpaConfig {
@Bean
public AuditorAware<Long> testAuditorAware() {
return () -> {
return Optional.of(new Random().nextLong());
};
}
}
@Profile을 이용하여 구분해 주지 않으면 컨트롤러 테스트 시 아래와 같은 에러가 발생한다. 동일한 이름의 빈이 등록되어 발생하는 문제.
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'jpaAuditingHandler' could not be registered. A bean with that name has already been defined and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
2024-10-15 15:04:50.603 ERROR 2760 --- [ main] o.s.test.context.TestContextManager : Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@4c398c80] to prepare test instance [com.tlog.backend.post.PostControllerTest@6e041285]
java.lang.IllegalStateException: Failed to load ApplicationContext
3. 테스트 적용
기존에 Jpa를 적용하기 위해 적용한 @Import(JpaConfig.class) -> @Import(TestJpaConfig.class)로 변경해준다.
@ActiveProfiles("test")
@Import(TestJpaConfig.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class PostRepositoryTest {
...
}
4. 결과
테스트 성공!
이제 번거롭게 테스트 할 때 마다 코드를 변경하고 커밋할 때 원상복구하지 않아도 된다.
참고 사이트:
spring-data-audit/src/test/java/pl/solutions/software/sokolik/bartosz/config/TestAuditingConfiguration.java at master · bartosz
Spring Boot with Hibernate Envers. Contribute to bartoszsokolik/spring-data-audit development by creating an account on GitHub.
github.com
https://umanking.github.io/2019/04/12/jpa-audit/
[JPA] Auditing 사용하기
Spring Data JPA의 Audit 기능에 대해서 알아보자.
umanking.github.io
'jpa' 카테고리의 다른 글
Auditing 사용해서 데이터 관리하기 (0) | 2024.10.02 |
---|---|
saveAll()을 사용하기 위해 List<DTO>를 List<Entity>로 변환 (0) | 2022.11.03 |