kkokkio - 프로젝트/트러블슈팅

Test Code Redis Connection Error

파란배개 2025. 6. 16. 07:17

문제 개요

오류 상황과 영향 범위 (예: 특정 코드 실행 시 발생, 특정 라이브러리 버전 호환 문제 등) 발생 배경 (예: 코드 테스트 중, 배포 중 문제 발견 등)

오류 상황

  • RedisMessageListener 생성 후 workflows를 탈 때 테스트가 모두 Redis 연결 오류로 인해 실패하는 현상

발생 배경

  • workflows에 따라 CI 테스트 중 Errror 발생

오류 메시지 및 원인 분석

오류 코드, 오류 메시지 포함 HTTP 상태 코드, 애플리케이션 로그, 서버 로그 등 구체적인 오류 정보 정리 및 로그 메시지를 통한 분석 제공 문제 발생 원인에 대한 심층 분석

오류 코드

원인 분석

  • RedisMessageListenerContainer가 기동되는 과정에서 Lettuce 드라이버가 기본 localhost:6379에 Redis 서버 접속을 시도하다가 Connection refused 예외가 발생
  • 이로 인해 RedisListenerExecutionFailedException → RedisConnectionFailureException → ApplicationContextException 순으로 예외가 전파되면서 스프링 애플리케이션 컨텍스트가 로드되지 못함
  • 따라서 contextLoads()를 포함한 모든 테스트에서 ApplicationContext가 초기화되지 않아 연쇄적으로 실패가 발생

해결 및 고민 과정

처음 문제를 접했을 때 고려했던 대안들과 선택하지 않은 이유 실험적으로 적용한 방법이 실패한 사례와 그 이유 여러 해결책 중 최적의 방안을 선택한 과정

해결 방안

  1. 테스트용 임베디드 Redis 추가
    • io.github.kstyrc:embedded-redis 같은 라이브러리로 JVM 내부에 Redis를 띄워 두면, Lettuce가 연결에 성공하여 Listener가 정상 동작합니다.
  2. 테스트 프로파일에서 Redis 빈 비활성화
    • @Profile("!test") 또는 @ConditionalOnProperty 등을 이용해, 테스트 실행 시 RedisMessageListenerContainer와 RedisExpiredKeyListener, JwtAuthenticationFilter에 주입되는 RedisTemplate 빈이 로드되지 않도록 분리합니다.
  3. 테스트 클래스에 Redis 관련 빈 목(Mock) 주입
    • @MockBean RedisTemplate<String,String> 혹은 @ImportAutoConfiguration(exclude = {RedisAutoConfiguration.class, RedisRepositoriesAutoConfiguration.class}) 처럼, Redis 자동 구성을 끄고 목으로 대체하여 컨텍스트 로드를 통과하게 합니다.

3-1. 추상 베이스 클래스에 한번 선언 후 상속하는 방법

  • 단 한 번만 컨테이너를 띄우고
  • Redis 호스트/포트 프로퍼티 주입도 한 번만 정의
  1. 현재 workflows에서 Redis 컨테이너가 구동되지 않았다는 문제 확인
    • workflows의 ci에서 Redis 컨테이너가 구동하지 않았다는 문제를 확인하여 workflows에 구동 로직을 포함 할 필요성 있음

고민 과정

  • 테스트용 임베디드 Redis 추가
    • 로컬에서의 테스트 코드에서는 Redis 관련 문제가 없어서 굳이 해야할 필요성을 못느낌
  • 테스트 프로파일에서 Redis 빈 비활성화
    • Redis를 활용해야하는 Testcode도 존재하기 때문에 비활성화해서는 안됨
  • 테스트 클래스에 Redis 관련 빈(Mock) 주입 또는 상속
    • 모든 테스트에 Redis 관련 빈 주입 또는 상속을 진행해야하는 문제점

최종 해결책 및 구현

문제 해결을 위한 단계별 조치 방법과 코드 예시 (예: 특정 애노테이션 추가, 라이브러리 버전 조정, 설정 변경 등) 참고 자료 (관련 공식 문서, 개발자 커뮤니티 게시물 등)

  • 단순히 RedisListenerConfig에 @Profile(”!test”)를 붙임으로서 test코드에서 빈을 등록하지 않도록 설정하여 문제를 해결함.

추가 개선점

유사한 문제를 방지하기 위한 주의할 점 (예: 애노테이션 명시 여부, 프레임워크 업데이트 주기 확인 등) 문제 해결 과정에서 배운 점 및 중요한 교훈 공유 보안 고려 사항 추가 (해결 과정에서 발생할 수 있는 보안 리스크 및 예방 조치 포함)

  • 테스트에서 불필요한 빈의 처리 방법을 알 수 있었다. 추후 같은 문제를 마주하여도 해결하는 방법을 알 수 있는 시간이었다.