miniredis 实例需动态获取地址、用 t.cleanup 清理、手动 flushall 隔离数据、预设数据优先调用 s.set,go-redis v8 连接需非空 addr 字符串,超时和 watch/scan 等边界行为需集成测试补充。

启动 miniredis 实例时,别硬写 127.0.0.1:6379
miniredis 默认不监听固定端口,每次 Run() 都会随机绑定一个空闲端口。直接在 redis.Options{Addr: "127.0.0.1:6379"} 里写死地址,测试必连不上,报 dial tcp 127.0.0.1:6379: connect: connection refused。
- 必须用
s.Addr()动态获取地址,它返回类似"127.0.0.1:52341"的字符串 - 推荐用
miniredis.RunT(t):自动处理失败 panic、绑定t.Cleanup,比手写Run()+defer s.Close()更安全 - 并发测试(
t.Parallel())下,defer s.Close()会错乱关闭——必须改用t.Cleanup(s.Close)
测试间数据不隔离?那是你没调 FlushAll()
miniredis 实例复用时,数据不会自动清空。上一个 test 写了 "user:1",下一个 test 就能读到——这不是 bug,是设计如此。想每个 test 干净起步,得手动重置。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 最稳妥:每个 test 开头调
s.FlushAll(),它是同步操作,线程安全 - 别依赖 “新建实例” 来隔离:虽然可行,但启动开销虽小,积少成多仍拖慢 CI
- 预设测试数据优先用
s.Set("k", "v")或s.HSet("h", "f", "v"),比走 client 发命令更快、更稳、不抛错
用 go-redis v8 连不上的常见原因
redis.NewClient() 在 v8 版本对 Addr 字段非常敏感:为空、为 nil、或格式不对都会 panic,错误信息常是 invalid address 或直接 panic。
-
Addr必须是非空字符串,且只能是"host:port"格式(不支持 unix socket、sentinel 等) - 别传
nil或空字符串给redis.Options;哪怕只填Addr,其他字段留默认即可 - 若用
redis.UniversalClient(比如兼容哨兵/集群),miniredis 只支持单节点模式,必须用redis.NewClient()
别被 miniredis 的“快”骗过,超时逻辑照样得测
真实 Redis client 默认带 5s 超时和重试,而 miniredis 响应在微秒级。你代码里漏传 context.Context 或没检查 .Err(),测试永远过,线上一抖就挂。
- 主动构造超时路径:用
ctx, _ := context.WithTimeout(context.Background(), time.Microsecond)调你的函数 - 验证是否返回
context.DeadlineExceeded,而不是静默失败或 panic - WATCH/EXEC 在 miniredis 中永远成功,SCAN 游标不迭代分页——这些边界行为没法 mock,得靠集成测试兜底
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










