“테스트 돌리는데 갑자기 ApplicationContext가 안 뜬다?”
요즘 통합 테스트를 정리하면서 @SpringBootTest 기반의 테스트를 하나씩 만들고 있었는데, 갑자기 이런 에러를 만났다.
No qualifying bean of type 'org.springframework.security.oauth2.client.registration.ClientRegistrationRepository'
ApplicationContext 자체가 죽어버린다. 로그 맨 아래에 IllegalStateException이 나오고,
“ApplicationContext failure threshold exceeded” 같은 문구까지 뜨면 거의 시험지 찢을 타이밍이다.
🤔 원인
문제의 근원은 SecurityConfig에 있는 http.oauth2Login()이었다.
Spring Security는 이걸 설정하면 자동으로 ClientRegistrationRepository와 OAuth2AuthorizedClientService가 빈으로 등록돼 있을 거라 믿는다.
하지만 테스트 환경에선 그런 빈 안 만들었기 때문에…
NoSuchBeanDefinitionException: ClientRegistrationRepository
이렇게 되는 것.
🔧 해결법: @MockBean 한 줄이면 OK
테스트 클래스에 이 두 줄을 추가하면 깔끔하게 해결된다.
@MockBean \
private ClientRegistrationRepository clientRegistrationRepository;
@MockBean
private OAuth2AuthorizedClientService oAuth2AuthorizedClientService;
딱 이거면 끝.
OAuth2 관련 인증 플로우 자체는 테스트에서 쓰지 않으니까 mock 처리로 충분하다.
✨ 여기에 팁 하나 더
추후엔 이런 설정이 여러 테스트에 반복될 수 있기 때문에,
아예 SecurityConfig 안에서 프로파일로 분기 처리하면 더 깔끔하다.
if (!Arrays.asList(env.getActiveProfiles()).contains("test")) {
http.oauth2Login();
}
→ 이렇게 하면 test 환경에서는 oauth2Login() 자체를 건너뛴다.
✅ 덤으로 정리한 체크리스트
- SecurityConfig에서 oauth2Login() 사용 시 주의
- ClientRegistrationRepository, OAuth2AuthorizedClientService는 mock으로 대체 가능
- @SpringBootTest에선 생각보다 많은 빈들이 다 같이 로딩된다
- 테스트 목적이 명확하다면 @MockBean은 강력한 무기!
마무리
사실 이거 하나 때문에 멀쩡하던 contextLoads()까지 다 실패해서 한참 헤맸다.
이 글을 보는 사람들은 나처럼 삽질하지 않길 바라며 🙏
앞으로는 인증 쪽은 따로 분리해서 테스트할 수 있게 좀 더 구조를 다듬어봐야겠다!