본문 바로가기

jpa

테스트용 AuditorAware 별도로 만들기

이전 게시글(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와 똑같은 패키지 구조로 생성했다.

TestJpaConfig.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. 결과

테스트 성공!

 

테스트 성공 화면

 

이제 번거롭게 테스트 할 때 마다 코드를 변경하고 커밋할 때 원상복구하지 않아도 된다.

 

참고 사이트:

https://github.com/bartoszsokolik/spring-data-audit/blob/master/src/test/java/pl/solutions/software/sokolik/bartosz/config/TestAuditingConfiguration.java

 

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