https://github.com/microsoftarchive/redis -> Rleases에서 .msi 설치 폴더로 설치
cd "Redis가 설치된 폴더 경로"
redis-server.exe redis.windows.conf
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RedisProperties {
private int redisPort;
private String redisHost;
public RedisProperties(
// appliaction.properties에 포트 번호와 아이피 주소 설정이 가능하다.
@Value("${spring.data.redis.port}") int redisPort,
@Value("${spring.data.redis.host}") String redisHost) {
this.redisHost = redisHost;
this.redisPort = redisPort;
}
public int getRedisPort() {
return redisPort;
}
public String getRedisHost() {
return redisHost;
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
@Configuration
@EnableRedisRepositories
public class RedisConfiguration {
@Bean
public RedisConnectionFactory redisConnectionFactory(RedisProperties properties){
return new LettuceConnectionFactory(properties.getRedisHost(), properties.getRedisPort());
}
@Bean
public StringRedisTemplate redisTemplate(RedisConnectionFactory connectionFactory){
StringRedisTemplate redisTemplate = new StringRedisTemplate();
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
}
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, String> {
}
import java.util.UUID;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;
@RedisHash("user")
public class User {
@Id
UUID uuid;
String name;
public User(UUID uuid, String name) {
this.uuid = uuid;
this.name = name;
}
}
//레디스 저장 테스트
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
@SpringBootApplication
public class RedisSpringBootTestApplication {
@Bean
CommandLineRunner runner(UserRepository repository) {
return args -> {
UUID uud = UUID.randomUUID();
User user = new User(uud, "name");
repository.save(user);
};
}
public static void main(String[] args) {
SpringApplication.run(RedisSpringBootTestApplication.class, args);
}
}
// build.gradle에 의존성 추가
implementation("it.ozimov:embedded-redis:0.7.2")
package com.example.redisspringboottest;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import org.springframework.boot.test.context.TestConfiguration;
import redis.embedded.RedisExecProvider;
import redis.embedded.RedisServer;
import redis.embedded.util.Architecture;
import redis.embedded.util.OS;
@TestConfiguration
public class TestRedisConfiguration {
private static RedisServer redisServer;
public TestRedisConfiguration(RedisProperties redisProperties) throws IOException {
this.redisServer = new RedisServer(/*
운영 체제별 RedisExecProvider로 설정할 수 있다.
getRedisPath() */redisProperties.getRedisPort());
}
// private RedisExecProvider getRedisPath() {
// RedisExecProvider customProvider = null;
// customProvider = RedisExecProvider.defaultProvider()
// .override(OS.UNIX, "/path/unix/redis")
// .override(OS.WINDOWS, Architecture.x86_64, "C:/Redis")
// .override(OS.MAC_OS_X, Architecture.x86_64, "/path/macosx/redis");
//
// return customProvider;
// }
@PostConstruct
public void redisServer() {
redisServer.start();
}
@PreDestroy
public void stopServer() {
redisServer.stop();
}
}
package com.example.redisspringboottest;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.util.UUID;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest(classes = TestRedisConfiguration.class)
public class UserRepositoryIntegerationTest {
@Autowired
private UserRepository userRepository;
@Test
@DisplayName("멤버 저장 확인")
void shouldSaveUser_toRedis(){
UUID uuid = UUID.randomUUID();
User user = new User(uuid, "name");
User saved = userRepository.save(user);
assertNotNull(saved);
User user1 = userRepository.findAll().iterator().next();
assertNotNull(user1);
}
}
// build.gradle에 의존성 추가
testImplementation 'org.testcontainers:testcontainers:1.19.3'
testImplementation "org.testcontainers:junit-jupiter:1.19.3"
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
@Testcontainers
public class TestRedisContainerConfiguration {
// 도커에서 다운받은 redis 이미지의 overview 페이지에서 지원하는
// Redis 이미지 버전을 적어주면 된다 redis: 이미지 버전 명
private static final String REDIS_IAMEGE = "redis:7.2.4-alpine";
private static final int REDIS_PORT = 6379;
@Container
private static final GenericContainer REDIS_CONTAINER =
new GenericContainer(DockerImageName.parse(REDIS_IAMEGE)).withExposedPorts(REDIS_PORT);
@DynamicPropertySource
private static void registerRedisProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.redis.host", REDIS_CONTAINER::getHost);
registry.add("spring.data.redis.port", () -> REDIS_CONTAINER.getMappedPort(REDIS_PORT).toString());
}
@Test
void givenRedisContainerConfiguredWithDynamicProperties_whenCheckingRunningStatus_thenStatusIsRunning() {
assertTrue(REDIS_CONTAINER.isRunning());
}
}
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.util.UUID;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest()
public class UserRepositoryIntegerationTest {
@Autowired
private UserRepository userRepository;
@Test
@DisplayName("멤버 저장 확인")
void shouldSaveUser_toRedis(){
UUID uuid = UUID.randomUUID();
User user = new User(uuid, "name");
User saved = userRepository.save(user);
assertNotNull(saved);
User user1 = userRepository.findAll().iterator().next();
assertNotNull(user1);
}
}
결과는 잘 나오지만, 첫 통합 테스트 이후에 다시 동작하려니 문제가 발생했다.
다시 gradle build를 하니 테스트가 정상적으로 동작하는 것을 확인 했다.
이유를 찾아보니 Gradle이 테스트코드의 변화가 없다면 통합 테스트를 캐싱하여 저장한다.
//linux and mac
./gradlew clean test --no-build-cache
//window
gradlew clean test --no-build-cache
깃허브 소스코드
Redis SpringBoot Data Redis 로컬/통합 테스트 환경 구축하기
Embedded Redis Server with Spring Boot Test
embedded-redis 깃허브 주소
레디스객체
Strategy 전략 프로젝트
Test events were not received" when run tests using Intellij