Spring Boot 테스트 삽질기 & @EnableJpaAuditing 이슈 해결

송현진·2025년 4월 1일
0

Spring Boot

목록 보기
3/23

✅ 오늘 한 일

  • UserController/api/signup API에 대한 유효성 검증 실패 테스트 코드를 작성했다.
  • Spring Boot 3.4.4 환경에서 @WebMvcTest를 기반으로 컨트롤러 단위 테스트를 구현했다.
  • @Valid 유효성 검사가 제대로 동작하는지 검증했고, GlobalExceptionHandler가 잘 작동하는지도 함께 확인했다.

❌ 삽질의 시작 - 테스트가 자꾸 404 혹은 컨텍스트 로딩 실패

처음 테스트를 실행했을 때 400(Bad Request)를 기대했지만, 실제로는 404(Not Found)가 발생하거나 아예 ApplicationContext 자체가 뜨지 않는 문제가 반복되었다.

주요 에러 메시지들

주요 에러 메시지들:

  • Status expected:<400> but was:<404>
  • JPA metamodel must not be empty
  • No qualifying bean of type 'JwtProvider'
  • No static resource api/signup

🛠️ 문제 분석 및 해결 과정

1. @EnableJpaAuditing 위치의 중요성

처음에는 @EnableJpaAuditing을 CoupangcloneApplication 클래스에 붙여 사용했지만,
이 방식은 모든 실행 환경(Spring Boot 실행, 테스트 포함)에서 무조건 JPA 메타모델을 필요로 하게 만든다.

특히 @WebMvcTest 같은 슬라이스 테스트에서는 JPA 관련 설정을 로딩하지 않기 때문에, JpaMetamodel must not be empty 같은 에러가 발생한다.

즉, 테스트에서도 CoupangcloneApplication이 항상 로드되기 때문에 @EnableJpaAuditing은 테스트를 방해하게 된다.

✅ 그래서 해결 방법으로 @EnableJpaAuditingSecurityConfig로 옮겼다.

@EnableJpaAuditing 위치 변경 예시

// 여기에서 @EnableJpaAuditing 관리하다 제거
@SpringBootApplication
public class CoupangcloneApplication {

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

@Configuration
@EnableWebSecurity
@EnableJpaAuditing  // 여기 추가해 SecurityConfig에서 관리
@RequiredArgsConstructor
public class SecurityConfig {
		....
}

2. @WebMvcTest는 슬라이스 테스트다!

@WebMvcTest(UserController.class)는 컨트롤러와 관련된 빈만 로드한다. 서비스, 리포지토리, 시큐리티 필터 등은 로드되지 않는다.

그래서 UserServiceJwtProvider 와 같은 의존성은 직접 수동 주입해줘야 했다.

이를 위해 @TestConfiguration으로 DummyConfig 작성하고, Mockito.mock(...)으로 가짜 빈 주입.

3. 404 에러의 진짜 원인

처음엔 API 매핑이 안 된 줄 알았는데, 실제로는 Spring Security 필터에 의해 요청이 차단되면서 404 Not Found가 발생하고 있었다.

그래서 @AutoConfigureMockMvc(addFilters = false)@EnableJpaAuditing을 받아오는 SecurityFilterChain 자체를 비활성화하고 정상적으로 API가 매핑되도록 조치했다.

✏️ 현재는 @WebMvcTest 테스트에서 @AutoConfigureMockMvc(addFilters = false)를 통해 SecurityConfig가 로딩되지 않도록 했기 때문에 @EnableJpaAuditing으로 인한 에러는 발생하지 않는다.

하지만 향후 @SpringBootTest와 같은 통합 테스트를 진행할 경우에는 SecurityConfig가 함께 로딩되며 문제가 발생할 수 있기 때문에, @EnableJpaAuditing에는 @Profile("!test") 조건을 붙여 테스트 환경에서 제외해두는 것이 더 안전한 방식이다.

📝 배운점

  • @EnableJpaAuditing은 반드시 JPA 메타모델이 존재해야 하므로, 테스트에서는 로딩되면 안 된다.
    • 테스트는 항상 Application.class로부터 시작되므로, 글로벌 설정은 테스트 환경까지 영향을 미친다는 점을 명심하자.
  • @WebMvcTest는 Web Layer만 테스트하므로, 필요 빈은 따로 @MockBean 또는 @TestConfiguration으로 주입해줘야 한다.
  • 404 Not Found는 정말로 API가 없다는 뜻이 아닐 수도 있다. 컨트롤러 매핑 실패, 시큐리티 차단, 의존성 미주입 등 다양한 원인이 존재할 수 있다.
  • MockMvc를 쓰면 실제 API 호출 흐름처럼 테스트 가능하므로, 유효성 검증 테스트는 진짜 API 수준에서 확인하는 것이 좋다.
profile
개발자가 되고 싶은 취준생

0개의 댓글