RSpec中Rails缓存未生效致测试失败,求排查思路
问题分析与解决
核心问题出在缓存的是ActiveRecord关系对象,而非实际查询结果:
你在控制器中使用Article.all,它返回的是ActiveRecord::Relation实例——这是一个延迟加载的查询对象,并不会立即执行SQL。当你把这个对象存入缓存时,缓存的只是查询条件,而非具体的文章数据。
第一次请求时,缓存未命中,执行Article.all并将关系对象存入缓存;第二次请求从缓存取出该对象后,在序列化为JSON时才会触发SQL查询,此时数据库里已经新增了第3条文章,所以返回的结果是3条,导致测试失败。
解决方案
1. 缓存实际数据而非关系对象
修改控制器代码,将查询结果转为数组(或强制加载),确保缓存的是具体数据:
module Api::V1 class ArticlesController < Api::V1::BaseController def index @articles = Rails.cache.fetch(Article.cache_key) do p "IT IS A MISS" Article.all.to_a # 转为数组,立即执行SQL并缓存结果集 end end end end
或者使用load方法强制加载数据:
Article.all.load
2. 确认测试环境缓存配置
确保测试环境使用的是实际生效的缓存存储,而非null_store(默认可能禁用缓存)。在config/environments/test.rb中设置:
config.cache_store = :memory_store
调整后,第一次请求会将包含2条文章的数组存入缓存,第二次请求直接返回缓存的数组,不会再查询数据库,测试即可通过。
内容的提问来源于stack exchange,提问作者Sig
相关产品推荐
相关产品推荐

