WebMvcTest 도중 Jpa 메타모델과 관련한 오류를 마주한다면?

문제 상황: WebMvcTest에서 JPA 관련 오류 발생

타임피스 프로젝트에 컨트롤러 테스트 코드를 추가하던 중 의외의 문제에 부딪혔습니다. @WebMvcTest를 사용했는데 JPA 메타모델과 JpaAuditing 관련 에러가 발생했습니다.

@WebMvcTest는 웹 계층과 관련된 컨텍스트만 로드하는 것이 목적인데(필터, 컨버터, 인터셉터, 시큐리티 필터체인 등), 왜 JPA 관련 모듈 에러가 발생한 것일까요?

원인 분석

그 답은 Spring Boot 공식 문서에서 그 답을 찾을 수 있었습니다:

If you use a test annotation to test a more specific slice of your application, you should avoid adding configuration settings that are specific to a particular area on the main method's application class.

문제의 핵심은 테스트 코드 실행 시점에 있었습니다. 테스트 코드가 실행될 때 기본적으로 main 메소드가 선언된 클래스를 기반으로 컴포넌트 스캔이 시작됩니다.

@EnableConfigurationProperties(CorsProperties.class)
@OpenAPIDefinition(servers = {@Server(url = "/", description = "Default Server url")})
@EnableJpaAuditing
@EnableAspectJAutoProxy
@SpringBootApplication
public class TimepieceApplication {

    public static void main(String[] args) {
        SpringApplication.run(TimepieceApplication.class, args);
    }
}

제 메인 애플리케이션 클래스에는 많은 어노테이션이 선언되어 있었고, 그 중 @EnableJpaAuditing이 포함되어 있었습니다. 테스트 실행 시 이 클래스를 베이스로 컴포넌트들을 스캔하면서 JPA 관련 기능을 찾으려고 했지만, @WebMvcTest는 웹 계층만 로드하기 때문에 JPA 관련 빈이 없어 에러가 발생했던 것입니다.

해결 방법

해결 방법은 크게 두 가지가 있었습니다:

  1. Configuration 클래스 분리
  2. 테스트 실행 시 사용할 베이스를 따로 지정

간단한 첫 번째 방법을 선택했습니다. JPA 관련 설정을 별도의 Configuration 클래스로 분리하여 테스트 환경에서 영향을 주지 않도록 했습니다.

@EnableJpaAuditing
@Configuration
public class JpaAuditingConfig {
}

@EnableConfigurationProperties(CorsProperties.class)
@OpenAPIDefinition(servers = {@Server(url = "/", description = "Default Server url")})
@EnableAspectJAutoProxy
@SpringBootApplication
public class TimepieceApplication {

    public static void main(String[] args) {
        SpringApplication.run(TimepieceApplication.class, args);
    }
}

이렇게 JPA 관련 설정을 별도 클래스로 분리함으로써 @WebMvcTest가 메인 애플리케이션 클래스를 스캔할 때 JPA 관련 설정을 로드하지 않게 되어 문제가 해결되었습니다.

결론

Spring Boot의 테스트 슬라이싱 기능을 사용할 때는 메인 애플리케이션 클래스에 특정 영역에 관련된 설정을 넣지 않는 것이 좋습니다. 각 기능별로 설정 클래스를 분리하면 테스트 환경에서 불필요한 컨텍스트 로딩을 방지할 수 있고, 결과적으로 테스트 실행 속도도 향상됩니다.

이 경험을 통해 테스트 환경과 애플리케이션 설정의 분리에 대해 다시 생각해보게 되었습니다. 여러분들도 비슷한 실수가 없길 바라겠습니다.

참고자료

https://docs.spring.io/spring-boot/reference/testing/spring-boot-applications.html#testing.spring-boot-applications.detecting-configuration

https://docs.spring.io/springboot/3.3/api/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTest.html

댓글