Projects/[Spring] Ticketing App Project

[Test] 분명 사용되지 않아서 지웠는데, 왜 테스트가 실패할까?

montmer27 2026. 3. 16. 21:25
요약
@MockBean private JwtTokenProvider jwtTokenProvider가 사용되지 않아 삭제했더니, 테스트가 모두 실패했다.
알고보니 @Import(SecurityConfig.class)에 의해서 SecurityConfig가 실제로 로드되는데, 내부적으로 JwtTokenProvider를 빈으로 주입받기 때문에 이를 삭제할 경우 SecurityConfig가 정상적으로 로드되지 않아 발생한 문제였다.

문제의 테스트 코드

그럼 여기서 본질적인 궁금증: 애초에 왜 @Import를 통해 SecurityConfig.class를 명시적으로 불러왔어야 했나?

@Import는 지정한 클래스를 빈으로 강제 등록하는 어노테이션이다.
@WebMvcTest는 웹 레이어 빈만 로드하기에(@Controller, @ControllerAdvice 등), @Service, @Repository, @Configuration 등은 자동으로 로드하지 않기 때문이다. 이는 @WebMvcTest가 컨텍스트를 제한적으로 로드하는 슬라이스 테스트이기 때문이다.
 SecurityConfig는 @Configuration 클래스였기 때문에, @WebMvcTest가 자동으로 로드하지 않아 @Import를 통해 강제 등록한 것이다.

그럼 더 나아가서, 애초에 전체 컨텍스트를 올리는 @SpringBootTest를 했으면 되지 않았을까?

그럼 이 테스트의 목적과 어긋나게 된다.
이 테스트(AdminUserControllerTest)의 의도는 컨트롤러 레이어만 테스트하는 것이다.
그래서 AdminUserService, UserService를 @MockBean으로 대체한 것이다.
(@Mock이 아니라 @MockBean을 사용하는 이유는 이전 게시물을 참고하라)

또한, @SpringBootTest는 모든 빈을 띄우기 때문에 테스트 속도가 느리다.
컨트롤러의 기능을 빠르게 테스트하기 위한 목적에 어긋날 뿐만 아니라, @MockBean으로 대체하지 않은 빈들이 실제로 동작하려다 설정 문제가 생길 수도 있다고 한다.

결론: @MockMvc와 같은 슬라이스 테스트에서는 컨텍스트가 제한적으로 띄워지기에, 일부 클래스들(@Configuration, @Service, @Repository 등)을 테스트에서 사용하고자 하는 경우 @Import(파일명.class)를 사용하여 강제로 주입해주면 된다.

이 글을 쓰는 나의 심정