TIL(Today I Learned)

TIL - Spring Boot Test 시 JPA metamodel must not be empty

Happy._. 2024. 7. 3. 08:03

Entity 클래스들에 공통으로 적용되는 BaseTimeEntity 클래스를 생성하면서 Application 클래스에 @EnableJpaAuditing 어노테이션을 적용했다.

서버를 실행 후 PostMan으로 데이터 등록 요청 테스트를 하면 DB에 정상적으로 데이터가 삽입되는 것을 확인할 수 있었다.

그런데 테스트 코드에서는 다음과 같은 메시지가 출력되면서 테스트를 할 수 없었다.

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaAuditingHandler': Cannot resolve reference to bean 'jpaMappingContext' while setting constructor argument
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': JPA metamodel must not be empty
Caused by: java.lang.IllegalArgumentException: JPA metamodel must not be empty
Error creating bean with name 'jpaAuditingHandler': Cannot resolve reference to bean 'jpaMappingContext' while setting constructor argument
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaAuditingHandler': Cannot resolve reference to bean 'jpaMappingContext' while setting constructor argument
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': JPA metamodel must not be empty
Caused by: java.lang.IllegalArgumentException: JPA metamodel must not be empty

 

해당 문제가 발생한 이유는 테스트 시에도 Application 클래스가 로드되는데 그 때 Application 클래스에 적용한 @EnableJpaAuditing로 인해 JPA 관련 Bean들을 필요로 한다.

@SpringBootTest를 사용하는 경우 전체 Context를 로드하고 JPA를 포함한 모든 Bean을 주입받기 때문에 에러가 발생하지 않지만 @WebMvcTest는 JPA 관련 Bean들을 로드하지 않기 때문에 문제가 발생하는 것이다.

 

이 문제를 해결하는 방법은 2가지가 있다.

 

첫 번째는 테스트 클래스 상단에 다음 어노테이션을 추가하는 방법으로 Entity가 사용되는 테스트 클래스마다 해당 어노테이션을 달아주어야 한다는 단점이 있다.

@MockkBean(JpaMetamodelMappingContext::class)

 

두 번째는 별도의 Config 파일을 생성해 다음과 같이 @EnableJpaAuditing를 적용해 주는 방법이 있다.

이 경우 첫 번째처럼 테스트 클래스마다 어노테이션을 추가하는 번거로움을 줄일 수 있다.

@EnableJpaAuditing
@Configuration
class JpaAuditingConfig {}

 

 

참고자료: https://tlatmsrud.tistory.com/140