본문 바로가기

Backend Development/Spring boot

Embedded Redis 로 redis junit 작성하기

Backend 를 개발할때  Cache 서버로 Redis Memory Server를 많이 사용한다. 그렇다면 JUnit 테스트 코드 작성시에도 간단하게 Redis Server를 사용할 수 있을까? 아래 라이브러리 및 설정을 활용하여 JUnit시   test embedded redis를 활용할 수 있다.

 

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.7.4</version>
</dependency>

<dependency>
    <groupId>it.ozimov</groupId>
    <artifactId>embedded-redis</artifactId>
    <version>0.7.3</version>
    <scope>test</scope>
</dependency>

 

위 it.ozimov 의 상세 정보는 아래 릴리즈 사이트에 가서 살펴볼수 있다.

https://github.com/ozimov/embedded-redis

 

라이브러리 다운로드 후 property 설정에 기본적인 테스트 Redis Server 설정을 지정한다. 간단히 host는 localhost 그리고 원하고자 하는 port를 지정한다.

 

application.properties

spring.redis.host=localhost
sprint.redis.port=16379

 

 

아래와 같이 설정 파일 및 Redis Operation 을 위한 소스를 작성한다.

 

TestRedisConfiguration

package com.sdp.common.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;

@Profile("unittest")
@Configuration
@EnableRedisRepositories
public class TestRedisConfiguration {

    private String redisHost;

    private int redisPort;


    public TestRedisConfiguration(@Value("${spring.redis.host}") String redisHost,
                                  @Value("${spring.redis.port}") int redisPort) {
        this.redisHost = redisHost;
        this.redisPort = redisPort;
    }

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration();
        redisConfiguration.setHostName(this.redisHost);
        redisConfiguration.setPort(this.redisPort);
        redisConfiguration.setDatabase(0);
        return new LettuceConnectionFactory(redisConfiguration);
    }

    @Bean(name = "redisTemplate")
    public RedisTemplate<?, ?> redisTemplate() {
        RedisTemplate<?, ?> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return redisTemplate;
    }
}

 

상세 서버 config설정을 아래 클래스를 통해 수행한다. 생성자의  setting("maxmemory 10M") 부분을 지정해 주어서 많은 JUnit 수행시에 메모리 full이 나지 않도록 적당한 사이즈를 직접 지정해주는것이 좋다.

 

TestRedisServerConfig

package com.sdp.common.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import redis.embedded.RedisServer;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Profile("unittest")
@Configuration
public class TestRedisServerConfig {

    private final RedisServer redisServer;

    public TestRedisServerConfig(@Value("${spring.redis.port}") int redisPort) {
        this.redisServer = RedisServer.builder()
                .port(redisPort)
                .setting("maxmemory 10M").build();
    }

    @PostConstruct
    public void startRedis() {
        this.redisServer.start();
    }

    @PreDestroy
    public void stopRedis() {
        this.redisServer.stop();
    }
}

 

아래는 위 설정한 redisTemplate bean을 주입받아 실제 오퍼레이션을 수행하는 util이다. 소스 공용화를 위해 실제 body는 RedisCommon으로 분리하였다.

 

TestRedisUtil

package com.sdp.common.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

@Profile("unittest")
@Service
public class TestRedisUtil extends RedisCommon {

    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate<String, String > redisTemplate;

    @PostConstruct
    public void init() {
    }
}

 

Redis의 실제 operation method를 담는 클래스

 

RedisCommon

package com.sdp.common.config;

import lombok.Data;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Map;

@Data
public class RedisCommon {

    private RedisTemplate<String, String> redisTemplate;

    public void insert(String nameSpace, String key, Map<String, String> data) {
        redisTemplate.opsForHash().putAll(nameSpace + key, data);
    }

    public Map<Object, Object> select(String nameSpace, String key) {
        Map<Object, Object> entries = redisTemplate.opsForHash().entries(nameSpace + key);
        return entries;
    }
}

 

-- The End --