运行两个测试时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
相关产品推荐
相关产品推荐

