Spring에서 Redis Test 하기

2024. 2. 12. 19:32· 개발/[우테코]
목차
  1. 0. 들어가기 전에
  2. 1. Redis 테스트는 어떻게 해야할까?
  3. 1.1 Embedded Redis
  4. 1.2 Test Container
  5. 2. 선택한 방법
  6. 3. 구현 방법
  7. ※ 참고



0. 들어가기 전에

Redis를 도입하면서 테스트 방법이 필요했는데 이에 대해 고민한 글입니다.



1. Redis 테스트는 어떻게 해야할까?

Reids를 도입하면서 테스트를 어떻게 해야할지에 대한 고민이 생겼다. 기존에는 MySQL 대신에 embeded h2를 사용해서 테스트를 했다. 하지만 redis를 도입하면서 이 방법은 사용할 수 없게 되었다. 찾아보니 레디스를 로컬에서 테스트하는 방법은 두 가지 방법이 있었다.

 

1.1 Embedded Redis

//spring-data-redis
compile('org.springframework.boot:spring-boot-starter-data-redis')
//embedded-redis
compile group: 'it.ozimov', name: 'embedded-redis', version: '0.7.2'

build.gradle에 embedded redis의 의존성을 추가해서 테스트를 하는 방법이다. 추가적인 설정이 필요하지만 h2 처럼 사용할 수 있다.

 

1.2 Test Container

testImplementation 'org.testcontainers:testcontainers:1.17.2'

 

2. 선택한 방법

결론적으로 Test Container를 사용하는 방법을 사용하기로 했다. 처음엔 Embedded Redis 사용해서 테스트를 하려고 했다. Embedded redis가 설정이 좀 더 쉽고, Test Container 보다 속도가 더 빠르기 때문이다. 하지만 MAC M1에서 이슈가 있었다. 해결방법이 있었지만 나중에 h2도 Test Container로 바꿀예정이기 때문에 두 번 변경하지 않게 Test Container를 선택했다.



3. 구현 방법

  • TestRedisContainerConfig
public class TestRedisContainerConfig implements BeforeAllCallback {

    private static final String REDIS_IMAGE = "redis:7.0.8-alpine";
    private static final int REDIS_PORT = 6379;

    private GenericContainer redisContainer;

    @Override
    public void beforeAll(ExtensionContext context) {
        redisContainer = new GenericContainer(DockerImageName.parse(REDIS_IMAGE))
                .withExposedPorts(REDIS_PORT);
        redisContainer.start();

        System.setProperty("spring.redis.host", redisContainer.getHost());
        System.setProperty("spring.redis.port", redisContainer.getMappedPort(6379).toString());
    }
}

테스트 속도를 위해 apline 이미지를 사용했다. BeforeAllCallBack의 beforeAll 메서드를 구현해서 모든 테스트가 실행되기 전에 테스트 컨테이너를 띄우도록 설정했다. 또한 사용할 클래스에 @ExtendedWith(TestRedisContainerConfig.class)로 선언해줘야한다.

  • TestRedisConfig
@Profile("test")
@Configuration
public class TestRedisConfig {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        final RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(host, port);
        return new LettuceConnectionFactory(redisStandaloneConfiguration);
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate() {
        final RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return redisTemplate;
    }
}

Redis에서 사용가능한 Serializer는 3종류가 있다.

  1. Jackson2JsonRedisSerializer

새로운 객체를 사용할 때마다 bean으로 등록해주어야 한다. 그렇기 때문에 RedisTemplate<String, T>로 사용할 수 있어 type casting이 없이 사용할 수 있다.

  1. StringRedisSerializer

ObjectMapper로 직렬화와 역직렬화를 해서 사용해야한다.

  1. GenericJackson2JsonRedisSerializer

RedisTemplate<String, Object> 형식으로 쓰이며 redis value를 조회할 때 type casting을 해줘야한다. 클래스의 패키지를 같이 저장하기 때문에 패키지가 변경되면 오류가 난다. MSA와 같은 환경에서 쓸 수 없다는 단점이 있다.

RedisTemplate을 이용해서 토큰 만료 기능(expire)만을 테스트할 예정이기 때문에, 간단하게 StringRedisSerializer를 사용했다.

  • TestRefreshTokenRepository
@Repository
public class TestRefreshTokenRepository {

    private final RedisTemplate<String, String> redisTemplate;

    public TestRefreshTokenRepository(final RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void save(final RefreshToken refreshToken) {
        redisTemplate.opsForHash().put(String.format("token:refresh:%s", refreshToken.getSocialId()), refreshToken.getToken().getValue(), Duration.ofSeconds(30));
    }

    public void expireRefreshToken(final RefreshToken refreshToken) {
        redisTemplate.expire(String.format("token:refresh:%s", refreshToken.getSocialId()), Duration.ZERO);
    }
}




※ 참고

  • SpringBoot Data Redis 로컬/통합 테스트 환경 구축하기
  • can not start for mac
  • Spring Boot – Testing Redis With Testcontainers
  • A Guide to JUnit 5 Extensions - life cycle callback
저작자표시

'개발 > [우테코]' 카테고리의 다른 글

락을 사용한 동시성 테스트하기  (1) 2024.02.27
확장을 고려해서 TaskScheduler로 자동 리뷰 완료 기능 구현하기  (0) 2024.02.20
Redis를 활용해서 RefreshToken 최적화하기  (0) 2024.02.08
바톤의 DB Replication  (0) 2023.10.14
build 할 때 Rest Docs 파일이 생성이 안되는 문제 트러블 슈팅  (0) 2023.08.20
  1. 0. 들어가기 전에
  2. 1. Redis 테스트는 어떻게 해야할까?
  3. 1.1 Embedded Redis
  4. 1.2 Test Container
  5. 2. 선택한 방법
  6. 3. 구현 방법
  7. ※ 참고
'개발/[우테코]' 카테고리의 다른 글
  • 락을 사용한 동시성 테스트하기
  • 확장을 고려해서 TaskScheduler로 자동 리뷰 완료 기능 구현하기
  • Redis를 활용해서 RefreshToken 최적화하기
  • 바톤의 DB Replication
쿠엔크
쿠엔크
우아한테크코스 5기 BE 에단 Github : https://github.com/cookienc
쿠엔크
기러기는 기록기록
쿠엔크
전체
오늘
어제
  • 분류 전체보기 (132)
    • CS (46)
      • [OS] (12)
      • [NETWORK] (10)
      • [DATABASE] (11)
      • [BASIC CONCEPT] (1)
      • [DATA STRUCTURE] (7)
      • [ALGORITHM] (5)
    • LANGUAGE (17)
      • [JAVA] (17)
    • DESIGN_PATTERN (2)
    • FRAMEWORK (18)
      • [SPRING] (18)
    • ORM (11)
      • JPA (11)
    • AWS (7)
    • BOOK (10)
      • [자바 웹 개발 워크북] (3)
      • [이펙티브 자바] (7)
    • 개발 (19)
      • [오류] (7)
      • [고민] (1)
      • [우테코] (10)
      • [iTracker] (1)
    • Tip (1)
      • [Plugins] (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • Effective Java
  • aws
  • JVM
  • CORS
  • 데이터베이스
  • 네트워크
  • ArgumentResolver
  • 디자인 패턴
  • 운영체제
  • 알고리즘
  • HTTP
  • JPA
  • 개념
  • 스프링
  • java
  • 오류
  • 자료구조
  • 가비아
  • 자바 웹 개발 워크북
  • Spring

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
쿠엔크
Spring에서 Redis Test 하기

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.