1. 概述
在使用 Spring Boot 开发 Redis 相关功能时,我们通常需要连接一个 Redis 实例。但在测试阶段,启动一个真实的 Redis 服务往往不够方便,比如 CI 环境部署麻烦、端口冲突等问题。
为了解决这些问题,我们可以使用嵌入式(Embedded)Redis 服务器,它可以在测试过程中自动启动,测试结束后自动关闭,无需手动管理 Redis 服务。
本文将介绍如何在 Spring Boot 测试中集成嵌入式 Redis,简化测试流程。
2. 引入依赖
首先,在 pom.xml
中添加以下依赖:
<!-- Spring Boot Redis 支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 嵌入式 Redis 实现 -->
<dependency>
<groupId>com.github.codemonstur</groupId>
<artifactId>embedded-redis</artifactId>
<version>1.4.2</version>
<scope>test</scope>
</dependency>
<!-- Spring Boot 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
✅ embedded-redis
是一个轻量级封装,用于在 Java 测试中启动本地 Redis 服务。
✅ spring-boot-starter-test
包含了 Spring Boot 测试所需的基础组件。
3. 配置 Redis 连接信息
接下来,我们需要配置 Redis 的连接参数,这里使用 application.properties
和 Java 配置类完成。
3.1 定义配置属性类
@Configuration
public class RedisProperties {
private int redisPort;
private String redisHost;
public RedisProperties(
@Value("${spring.data.redis.port}") int redisPort,
@Value("${spring.data.redis.host}") String redisHost) {
this.redisPort = redisPort;
this.redisHost = redisHost;
}
// 提供 getter 方法
}
3.2 配置 Redis 连接工厂
@Configuration
@EnableRedisRepositories
public class RedisConfiguration {
@Bean
public LettuceConnectionFactory redisConnectionFactory(
RedisProperties redisProperties) {
return new LettuceConnectionFactory(
redisProperties.getRedisHost(),
redisProperties.getRedisPort());
}
@Bean
public RedisTemplate<?, ?> redisTemplate(LettuceConnectionFactory connectionFactory) {
RedisTemplate<byte[], byte[]> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
return template;
}
}
⚠️ 上述配置使用了 Lettuce
作为 Redis 客户端,也可以替换为 Jedis
,但 Spring Boot 默认推荐 Lettuce。
4. 启动嵌入式 Redis 服务器
为了在测试中自动启动 Redis,我们需要创建一个测试专用的配置类,并结合 embedded-redis
实现自动启停。
4.1 配置 application.properties
在 src/test/resources/application.properties
中添加:
spring.data.redis.host=localhost
spring.data.redis.port=6370
4.2 创建测试配置类
@TestConfiguration
public class TestRedisConfiguration {
private RedisServer redisServer;
public TestRedisConfiguration(RedisProperties redisProperties) throws IOException {
this.redisServer = new RedisServer(redisProperties.getRedisPort());
}
@PostConstruct
public void postConstruct() throws IOException {
redisServer.start();
}
@PreDestroy
public void preDestroy() throws IOException {
redisServer.stop();
}
}
✅ 上述代码在 Spring 上下文初始化后启动 Redis 服务,销毁前自动关闭。
✅ 默认会使用系统路径下的 redis-server
,如果找不到,可以手动指定路径。
4.3 指定 Redis 可执行文件路径(可选)
this.redisServer = new RedisServer("/path/to/redis-server", redisProperties.getRedisPort());
也可以按操作系统指定不同路径:
RedisExecProvider customProvider = RedisExecProvider.defaultProvider()
.override(OS.UNIX, "/path/unix/redis")
.override(OS.Windows, Architecture.x86_64, "/path/windows/redis")
.override(OS.MAC_OS_X, Architecture.x86_64, "/path/macosx/redis");
this.redisServer = new RedisServer(customProvider, redisProperties.getRedisPort());
5. 编写测试用例
现在我们可以编写一个简单的集成测试来验证 Redis 是否正常工作。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestRedisConfiguration.class)
public class UserRepositoryIntegrationTest {
@Autowired
private UserRepository userRepository;
@Test
public void shouldSaveUser_toRedis() {
UUID id = UUID.randomUUID();
User user = new User(id, "name");
User saved = userRepository.save(user);
assertNotNull(saved);
}
}
✅ 该测试会自动启动嵌入式 Redis 服务,执行完测试后自动关闭。
✅ TestRedisConfiguration
需要显式传入 @SpringBootTest
,否则嵌入式服务不会启动。
6. 小结与建议
- ✅ 使用嵌入式 Redis 可以避免测试环境依赖真实 Redis 服务,提升测试效率。
- ✅ 推荐将 Redis 配置与主配置分离,便于测试与生产环境解耦。
- ❌ 当前
embedded-redis
不支持随机端口分配,建议测试时使用固定端口或自行封装随机端口逻辑。 - ✅ 适用于单元测试、CI 构建、本地集成测试等场景。
完整示例代码可在 GitHub 获取。