You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行两个测试时MockRedis失效,单独运行正常问题排查

问题分析与解决方案

我来帮你排查这个问题——单独跑测试没问题,一起跑就失败,这种情况大多是测试隔离没做好或者存根逻辑有漏洞,结合你的代码和报错信息,主要有两个可能的原因:

1. 错误的Redis存根方式

你用了receive_message_chain(:new)来存根Redis.new,但Redis.new是直接的类方法调用,根本不需要链式调用语法。这种错误的写法可能导致在多测试运行时,RSpec的mock重置机制没有正确覆盖前一个测试的存根,第二个测试里Redis.new没有返回你创建的MockRedis实例,自然也就看不到写入的key了。

修复方法

把存根代码改成直接针对new方法:

before do
  @redis_instance = MockRedis.new
  # 去掉receive_message_chain,直接用receive(:new)
  allow(Redis).to receive(:new).and_return(@redis_instance)
end

2. 测试对象未隔离

如果你的foo实例是在整个describe块外定义的(比如共享同一个实例),第一个测试调用paper_version('reduced')后,可能修改了foo的内部状态(比如方法里有“已缓存则跳过写入”的逻辑),导致第二个测试调用paper_version('full')时根本没执行Redis写入操作,所以@redis_instance.keys是空的。

修复方法

确保每个测试都使用全新的foo实例,把foo的初始化放到before块里:

before do
  @redis_instance = MockRedis.new
  allow(Redis).to receive(:new).and_return(@redis_instance)
  # 每个测试都新建一个foo实例
  @foo = Foo.create!(title: "测试文档") # 根据你的模型属性调整
end

it 'stores the reduced version on Redis Cache when paper_type == reduced ' do
  @foo.paper_version('reduced')
  expect(@redis_instance.keys).to include "reduced_paper_#{@foo.id}"
end

it 'stores the full version on Redis Cache when paper_type == full ' do
  @foo.paper_version('full')
  expect(@redis_instance.keys).to include "full_paper_#{@foo.id}"
end

额外排查技巧

如果还是有问题,可以在第二个测试里加个验证,确认Redis.new确实被调用了:

it 'stores the full version on Redis Cache when paper_type == full ' do
  expect(Redis).to receive(:new)
  @foo.paper_version('full')
  expect(@redis_instance.keys).to include "full_paper_#{@foo.id}"
end

如果这个测试失败,说明存根还是没生效,你可以进一步检查paper_version方法里调用Redis的逻辑是不是和你存根的方式匹配(比如有没有用Redis.new之外的方式初始化Redis客户端)。

内容的提问来源于stack exchange,提问作者Marco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:04:22