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가 초기화되지 않아 연쇄적으로 실패가 발생
해결 및 고민 과정
처음 문제를 접했을 때 고려했던 대안들과 선택하지 않은 이유 실험적으로 적용한 방법이 실패한 사례와 그 이유 여러 해결책 중 최적의 방안을 선택한 과정
해결 방안
- 테스트용 임베디드 Redis 추가
- io.github.kstyrc:embedded-redis 같은 라이브러리로 JVM 내부에 Redis를 띄워 두면, Lettuce가 연결에 성공하여 Listener가 정상 동작합니다.
- 테스트 프로파일에서 Redis 빈 비활성화
- @Profile("!test") 또는 @ConditionalOnProperty 등을 이용해, 테스트 실행 시 RedisMessageListenerContainer와 RedisExpiredKeyListener, JwtAuthenticationFilter에 주입되는 RedisTemplate 빈이 로드되지 않도록 분리합니다.
- 테스트 클래스에 Redis 관련 빈 목(Mock) 주입
- @MockBean RedisTemplate<String,String> 혹은 @ImportAutoConfiguration(exclude = {RedisAutoConfiguration.class, RedisRepositoriesAutoConfiguration.class}) 처럼, Redis 자동 구성을 끄고 목으로 대체하여 컨텍스트 로드를 통과하게 합니다.
3-1. 추상 베이스 클래스에 한번 선언 후 상속하는 방법
- 단 한 번만 컨테이너를 띄우고
- Redis 호스트/포트 프로퍼티 주입도 한 번만 정의
- 현재 workflows에서 Redis 컨테이너가 구동되지 않았다는 문제 확인
- workflows의 ci에서 Redis 컨테이너가 구동하지 않았다는 문제를 확인하여 workflows에 구동 로직을 포함 할 필요성 있음
고민 과정
- 테스트용 임베디드 Redis 추가
- 로컬에서의 테스트 코드에서는 Redis 관련 문제가 없어서 굳이 해야할 필요성을 못느낌
- 테스트 프로파일에서 Redis 빈 비활성화
- Redis를 활용해야하는 Testcode도 존재하기 때문에 비활성화해서는 안됨
- 테스트 클래스에 Redis 관련 빈(Mock) 주입 또는 상속
- 모든 테스트에 Redis 관련 빈 주입 또는 상속을 진행해야하는 문제점
최종 해결책 및 구현
문제 해결을 위한 단계별 조치 방법과 코드 예시 (예: 특정 애노테이션 추가, 라이브러리 버전 조정, 설정 변경 등) 참고 자료 (관련 공식 문서, 개발자 커뮤니티 게시물 등)
- 단순히 RedisListenerConfig에 @Profile(”!test”)를 붙임으로서 test코드에서 빈을 등록하지 않도록 설정하여 문제를 해결함.
추가 개선점
유사한 문제를 방지하기 위한 주의할 점 (예: 애노테이션 명시 여부, 프레임워크 업데이트 주기 확인 등) 문제 해결 과정에서 배운 점 및 중요한 교훈 공유 보안 고려 사항 추가 (해결 과정에서 발생할 수 있는 보안 리스크 및 예방 조치 포함)
- 테스트에서 불필요한 빈의 처리 방법을 알 수 있었다. 추후 같은 문제를 마주하여도 해결하는 방법을 알 수 있는 시간이었다.