Spring Boot JUnit5 : JPA metamodel must not be empty 에러 솔루션

2023. 10. 31. 14:46Project 해축갤/테스트 코드

728x90

상황

간단한 Controller Unit Test

아마 이 에러가 나신 분들은 Controller 에 대한

유닛 테스트 코드를 작성하고 실행하니 에러가 나셨을 겁니다.

 

많은 분들이 영한님의 Spring Data JPA 강의를 수강 후,

프로젝트 시작 시에 만들어지는 Applicaiton 파일에 붙여둔

@EnableJpaAuditing

@EnableJpaAuditing 어노테이션 때문에 에러가 나게 되는 겁니다.

어째서냐?

원인

@WebMvcTest 내부 javadoc 설명

Using this annotation will disable full auto-configuration and instead
apply only configuration relevant to MVC tests
(i.e. @Controller, @ControllerAdvice, @JsonComponent, Converter/GenericConverter, Filter,
WebMvcConfigurer and HandlerMethodArgumentResolver beans
but not @Component, @Service or @Repository beans)

번역 : 이 애노테이션을 사용하면 full auto-configuration 대신 MVC Test 에 관련한 config(설정) 만 들고옵니다.

즉,@WebMvcTest 는 JPA 관련한 세팅을 불러오지 않는 다는 것입니다.

 

좀 더 자세하게 알아보자면?

JUnit5 라는 Test Framework 가 어떻게 작동되냐에 대한 과정은 다음과 같습니다.

  1. 테스트 클래스 인스턴스 생성 (저의 경우 MemberControllerTest 인스턴스)
  2. Spring TestContext Framework 초기화
  3. Spring Application Context 초기화
  4. 의존성 주입
  5. 테스트 메서드 실행 전 설정 (JUnit5 기준 @BeforeEach 가 달린 함수, JUnit4 기준 @Before 가 달린 함수)
  6. 테스트 메서드 실행
  7. 테스트 메서드 실행 후 설정 (JUnit5 기준 @AfterEach 가 달린 함수, JUnit4 기준 @After 가 달린 함수)
  8. Spring TestContext Framework 정리

위 과정이 너무 복잡하다면 이렇게 생각하면 편할겁니다.

Spring TestContext Framework(Spring 이 만듬) 이 JUnit 에게 Spring 관련 Context 를 제공하고,
JUnit 이라는 Test Framework 가 받은 Context 로 테스트 환경을 구성한다.

이때 Context 란 위에서 얘기한
@Controller, @ControllerAdvice, @JsonComponent 이런 등등의 애노테이션 관련한 설정들이다

우리의 경우 문제가 생기는 부분은 3번, Spring Application Context 초기화에서 문제가 생기는 겁니다.

@WebMvcTest 라는 애노테이션을 달았으니 우리는 JPA 에 관한 설정 정보는 제공받지 않는다는 겁니다.

 

하지만 ~Application 파일에는 @EnableJpaAuditing 이라는 애노테이션과 함께 추가 정보를 요구하는 데

JUnit 은 제공받지 않으니 문제가 터지는 거죠.

해결 방법

1. 테스트 클래스에 @SpringBootTest 붙이기

이렇게 말이죠. 뭐 하나의 방법이기도 하고 솔루션이기도 합니다.

다만 저의 경우 이 테스트를 작성하는 목적은 이겁니다.

 

Controller '만' 잘 기능하는 지 확인하기

 

즉, 슬라이스 테스트를 하는 데 있어 딱 필요한 만큼의 설정을 불러와야

테스트도 빠를 겠죠 (불필요한 Bean 등록도 안해도 되고)

2. @MockBean 추가

@WebMvcTest 의 슬라이스 테스트에 @EnableJpaAuditing 관련 정보만 추가하자! 입니다.

통과!

다른 글에는 JpaMetamodelMappingContext.class 에 대해 나와있지 않아 내부적으로 까보니

대략 Jpa 관한 MetaData 들을 기반으로 구현한 MappingContext,

즉, @EnableJpaAuditing 에 필요한 Context 를 포함하고 있는 클래스라고 볼 수 있겠죠!

되긴 하지만, 2가지가 단점입니다.

  1. 매번 Controller 에 붙여야 한다 -> 중복, 귀찮음
  2. Controller 의 기능 테스트라, JPA 기능을 사용하지도 않는다.

즉 저는 이걸 사용하지는 않을 겁니다.

3. Configruation 분리 -> 이게 거의 정답

다른 분들의 블로그도 그렇고 제 생각도 이러합니다.

@EnableJpaAuditing

즉, Application 에 붙어있는 @EnableJpaAuditing 이 문제인것이죠.

@EnableJpaAuditing 의 설명을 보면 

annotation configuration 을 통해 auditing 을 enable 한다고 나와 있으니,

사실 Application 이 아니라 다른 곳에 있어도 @EnableJpaAuditing 은 잘 작동한다는 것입니다.

즉 별도의 클래스 생성 및 @Configuration, @EnableJpaAuditing 을 추가해주고

기존의 Applicaiton 파일에는 지워주면 됩니다!

편-안

결론

3. Configruation 분리 를 택하자!

참고

 

Spring TestContext Framework :: Spring Framework

The Spring TestContext Framework (located in the org.springframework.test.context package) provides generic, annotation-driven unit and integration testing support that is agnostic of the testing framework in use. The TestContext framework also places a gr

docs.spring.io

 

 

Spring Boot jUnit Test : JPA metamodel must not be empty! 에러 해결 방법

서론 Controller 테스트코드 작성 중 다음과 같은 에러를 만났다. 해당 에러를 어떻게 해결하는지 원인과 해결방법 2가지에 대해서 정리해보도록 하겠다. 에러 발생 원인 Controller에 관련된 @MockBean

jeongkyun-it.tistory.com

 

728x90