embedded redis 是非官方第三方库,需显式启动并配置测试环境,推荐使用 it.ozimov:embedded-redis:0.7.3,配合 application-test.yml 明确 host/port、禁用 ssl 和密码,并避免并发端口冲突。

Embedded Redis 不是 Spring Boot 官方组件,也没有内置启动能力,必须靠第三方库在测试时拉起一个真实但进程内托管的 Redis 实例。它比 @MockBean RedisTemplate 更真实,比连本地 Redis 更隔离,适合需要验证序列化、连接池、事务行为或 Lua 脚本执行的集成测试。
怎么选 embedded-redis 依赖
目前主流且仍在维护的是 it.ozimov:embedded-redis(0.7.x 系列),Spring Boot 2.4+ 和 3.x 都兼容。别用已归档的 com.github.kstyrc:embedded-redis(0.6.x),它不支持 Apple Silicon 和较新 JDK,且无 TLS/集群模式支持。
-
testImplementation 'it.ozimov:embedded-redis:0.7.3'是当前最稳的选择 - 务必加
<scope>test</scope>,避免污染主程序 classpath - 如果项目用了 Lettuce(Spring Boot 2.3+ 默认),无需额外配客户端——
LettuceConnectionFactory可直连localhost:6379
如何让 Embedded Redis 在测试前自动启动
不能只靠 @SpringBootTest 启动上下文,得显式管理生命周期。推荐用 @TestConfiguration + @PostConstruct/@PreDestroy 组合,而不是在每个测试类里重复写 start/stop。
- 定义一个
RedisServerMock组件,用@Component+@Profile("test")隔离环境 - 构造时传入端口(如
6379),避免和本地 Redis 冲突;也可用0让 OS 分配空闲端口,再通过getPort()获取 - 注意:
RedisServer启动是阻塞的,若测试并发跑多个类,需加synchronized或改用静态单例
application-test.yml 怎么配才不踩坑
测试配置必须覆盖生产配置,否则 LettuceConnectionFactory 还会去连 spring.redis.host 默认值(localhost)的 6379,而此时 embedded-redis 可能还没启好,导致 Connection refused。
- 在
src/test/resources/application-test.yml中明确指定:spring.redis.host: localhostspring.redis.port: 6379 - 禁用密码:
spring.redis.password:(空值),因为 embedded-redis 默认无认证 - 关闭 SSL:
spring.redis.ssl.enabled: false,embedded-redis 不支持 TLS - 可选:调小连接池参数,比如
lettuce.pool.max-active: 2,避免测试结束时连接未释放完报 warning
为什么测试偶尔失败:端口占用或初始化顺序问题
最常见的失败不是代码逻辑错,而是 timing 问题——RedisServer.start() 返回不等于 Redis 已 ready,Lettuce 可能抢在 INFO server 响应前就发了 PING,触发重试超时。
- 启动后加短延时(
Thread.sleep(300))只是权宜之计,不推荐 - 正确做法:用
GenericContainer(Testcontainers)替代 embedded-redis,尤其当测试涉及集群、哨兵或 Redis Modules 时 - 如果坚持用 embedded-redis,确保所有测试类都使用同一个 profile(如
@ActiveProfiles("test")),且RedisServerMock是@Primary的单例 - 特别注意:Maven Surefire 并行执行(
<parallel>methods</parallel>)会导致多个RedisServer尝试绑定同一端口,必须禁用或改用随机端口
java.lang.UnsatisfiedLinkError 或 Could not start redis server,优先检查是否混用了不同版本的 native 库,而不是怀疑代码逻辑。











