프로그래밍/Spring

[Spring] 테스트 코드에서 JPA metamodel must not be empty! 예외가 발생할 때

문제상황

게시글 생성 Controller 테스트를 작성하고 테스트를 하려는데 해당 에러를 만나게 됐다.

 

처음엔 Entity 설정을 뭔가 잘못했나 생각했는데 딱히 이상은 없었고, 잘 모르겠어서 검색을 해보았다.


문제점

에러가 발생한 이유는 Auditing 때문이다.

게시글의 작성일 필드 값을 자동으로 넣어주기 위해 Auditing 설정을 했는데,

@EnableJpaAuditing 을  App Class에서 설정을 해주었다. 

이렇게 한 설정은 실행할 때는 문제가 되진 않지만, 내가 작성한 테스트에서는 문제가 된다.

Spring 컨테이너를 요구하는 테스트는 가장 기본이 되는 @SpringBootApplication이 붙은 클래스가 항상 로딩이된다.

@EnableJpaAuditing이 해당 클래스에 등록되어 있어서 테스트를 진행할 때, 해당 JPA 관련 Bean들을 필요로 하고있는 상황이였다.

Controller 테스트를 작성할 때, @WebMvcTest 사용했는데,
해당 테스트 어노테이션은 JPA 생성과 관련된 기능이 없는 어노테이션이다. 

그래서 해당 어노테이션을 사용해서 어플리케이션을 실행하지 않아 Jpa 관련된 Bean들을 생성을 못하게 되고 문제가 발생한 것이다.

 

@WebMvcTest는 다음과 같이 웹 계층과 관련된 빈들만을 찾아서 빈으로 등록한다.

일반적인 @Component나 @ConfigurationProperties 등을 사용하는 빈들은 스캔되지 않는다.

  • @Controller, @RestController
  • @ControllerAdvice, @RestControllerAdvice
  • @JsonComponent
  • Filter
  • WebMvcConfigurer
  • HandlerMethodArgumentResolver

해결방법

방법은 두 가지가 있다.

  1. @EnableJpaAuditing 어노테이션을 둘 Config 파일을 따로 만든다. 
    Config 설정을 만들어 어노테이션을 분리해준다면, 해당 Config파일이 빈으로 등록되지 않고,
    테스트 실행 시 Application이 JPA와 상관없이 정상 실행된다.

 

    2. 테스트 코드에 JpaMetaModelMapptingContext 클래스의 MockBean을 추가해준다.
       테스트 코드 실행 시 자동으로 JpaMetaModelMappingContext을 빈으로 등록해준다.

@WebMvcTest(XXXController.class)
@MockBean(JpaMetamodelMappingContext.class)

      이 방식은 Controller에 대한 모든 테스트에 추가해줘야한다.

 

 

나는 1번 방식을 통해 해결했다. 

이유는

  • @WebMvcTest를 사용하는 곳 (Controller테스트들..) 사용하는 곳이면 Auditing이 관련 없는데도 해당 구문을 넣어줘야한다.
  • 그에 반해 Config 파일을 한번만 분리해놓으면 신경을 안써도 된다. (테스트 코드와 의존성 제거는 덤!)
728x90