🧶 '프로그래머스 데브코스 4기 백엔드'에서 진행한 <네이버 웹툰 클론코딩> 팀 프로젝트 기록입니다.
문제 상황
Controller 테스트를 실행할 때 "JPA metamodel must not be empty!" 에러가 발생했다.
각 Controller 테스트는 @WebMvcTest
로 진행했다.
원인
@SprinbBootApplication
에 @EnableJpaAuditing
을 붙였는데, @WebMvcTest로 테스트를 진행해서 발생한 문제이다.
@EnableJpaAuditing이 뭔데?
ORM에서 Database Auditing이란 영속적 엔티티(persistent entity)와 관련된 이벤트들을 추적하고 로깅하는 것을 의미한다. 간단히 표현하자면, 엔티티 버전 관리를 뜻한다. 엔티티를 추적하기 위해서는 생성 시간이나 수정 시간, 변경한 사람과 같은 정보들이 각 엔티티마다 공통적으로 필요할 것이다.
JPA Auditing은 엔티티를 RDB에 매핑할 때 이러한 정보를 필드로 자동으로 넣어주는 기능이다. 그리고 @EnableJpaAuditing
어노테이션을 통해 JPA에서 Auditing을 활성화할 수 있다. Application 클래스나 @Configuration 클래스에 붙이면 된다.
우리도 엔티티들에 createdAt
, updatedAt
을 자동으로 넣어주고 싶었기 때문에 @SpringBootApplication
에 @EnableJpaAuditing
을 달아준 것이다.
@SpringBootApplication에 @EnableJpaAuditing을 붙이면...
@SpringBootApplication
과 @EnableJpaAuditing
을 같이 사용하면 JPA Auditing이 즉시 활성화되므로, @EnableJpaAuditing
은 자신이 필요로 하는 JPA 관련 빈들을 찾게 된다.
그러나 @WebMvcTest
를 이용해서 컨트롤러 계층만 테스트를 하도록 구성했기 때문에 이 테스트에 JPA 관련 빈들은 등록되어 있지 않으므로 "JPA metamodel must not be empty!" 에러가 발생하는 것이다.
@WebMvcTest
Spring MVC 컴포넌트에만 집중한 테스트에 사용되는 어노테이션이다. MVC 테스트와 관련된 configuration만 테스트에 적용할 수 있는데, 그중엔 아래와 같은 것들이 있다.
- @Controller
- @ControllerAdvice
- @JsonComponent
- Converter/GenericConverter
- Filter
- WebMvcConfigurer
- HandlerMethodArgumentResolver
@Component
, @Service
, @Repository
빈은 포함되지 않는다. 따라서 컨트롤러 테스트에서 자주 사용된다.
@WebMvcTest가 자동으로 구성하는 Configuration 목록
해결 방법
@WebMvcTest에 JpaMetamodelMappingContext.class MockBean 등록하기
@WebMvcTest(DefaultWebtoonController.class)
@MockBean(JpaMetamodelMappingContext.class)
class DefaultWebtoonControllerTest {
// 테스트 코드
}
아주 간단하다.
다만 모든 컨트롤러 테스트마다 @MockBean(JpaMetamodelMappingContext.class)
를 추가해야 한다는 단점이 있다.
@SpringBootApplication에서 @EnableJpaAuditing Configuration 분리하기
그래서 Configuration을 분리해주는 방법을 선택했다.
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@Configuration
@EnableJpaAuditing
public class JpaAuditingConfig {
}
그리고 @SpringBootApplication
에서 @EnableJpaAuditing
은 빼준다.
그러면 @WebMvcTest
에서 @EnableJpaAuditing
이 자동으로 활성화되지 않고, 당연히 JPA 관련 빈들을 필요로 하게 될 일도 없어져 에러가 발생하지 않는다.
📗 Reference
https://www.baeldung.com/database-auditing-jpa
https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/config/EnableJpaAuditing.html
'나의 개발일기' 카테고리의 다른 글
[Java/Spring] SpringSecurity(6.x 버전 이상)를 사용하면서 h2-console에 접속하기 (0) | 2023.10.28 |
---|---|
[Java/Spring] enum으로 코드를 개선해보자(2) : enum과 JPA, 그리고 AttributeConverter (0) | 2023.09.27 |
[Java/Spring] enum으로 코드를 개선해보자(1) : enum을 적용하게 된 과정 (0) | 2023.09.26 |