可选地在Rails 3function测试中测试缓存

通常,我希望我的function测试不执行动作缓存。 Rails似乎在我身边,在environment/test.rb默认为config.action_controller.perform_caching = false 。 这导致正常的function测试没有测试缓存。

那么我如何在Rails 3中测试缓存。

这个线程中提出的解决方案似乎相当hacky或者对Rails 2: 如何在rails中的function测试中启用页面缓存?

我想做的事情如下:

 test "caching of index method" do with_caching do get :index assert_template 'index' get :index assert_template '' end end 

也许还有更好的方法来测试缓存是否被击中?

你最终可能会互相踩踏测试。 您应该将其包装起来并确保将其重置为旧值。 一个例子:

 module ActionController::Testing::Caching def with_caching(on = true) caching = ActionController::Base.perform_caching ActionController::Base.perform_caching = on yield ensure ActionController::Base.perform_caching = caching end def without_caching(&block) with_caching(false, &block) end end 

我还把它放到一个模块中,这样你就可以把它包含在你的测试类或父类中。

rspec的解决方案:

在配置中添加带有自定义元数据键的around块。

 RSpec.configure do |config| config.around(:each, :caching) do |example| caching = ActionController::Base.perform_caching ActionController::Base.perform_caching = example.metadata[:caching] example.run Rails.cache.clear ActionController::Base.perform_caching = caching end end 

需要缓存时添加元数据键。

 describe "visit the homepage", :caching => true do # test cached stuff end 

我的版本有效:

 RSpec.configure do |config| config.around(:each) do |example| caching = ActionController::Base.perform_caching ActionController::Base.perform_caching = example.metadata[:caching] example.run Rails.cache.clear ActionController::Base.perform_caching = caching end end 

感谢罗斯蒂,但是

  1. 需要在示例之间清除缓存
  2. 缓存存储不能在示例上设置不同,只有在init时才会有人想知道

这是我目前解决问题的方法:在environment/test.rb设置

 config.action_controller.perform_caching = true 

另外,我是猴子修补Test::Unit::TestCase如下:

 class Test::Unit::TestCase def setup_with_disable_caching setup_without_disable_caching disable_caching end alias_method_chain :setup, :disable_caching def disable_caching ActionController::Base.perform_caching = false end def enable_caching(&blk) ActionController::Base.perform_caching = true if blk yield disable_caching end end end 

这允许我编写以下测试:

 test "info about caching (with caching)" do enable_caching do get :about, :locale => :en assert_template 'about' get :about, :locale => :en assert_template nil end end test "info about caching (without caching)" do get :about, :locale => :en assert_template 'about' get :about, :locale => :en assert_template 'about' end 

它并不完美,但现在可以使用。 我仍然对更好的想法感兴趣!!

这不是一个答案,而是要注意哪些不适合评论的一些限制。

  • 依赖于ActionController::Base.perform_caching所有(惊人)答案都不适用于低级缓存 (参见此答案 )。 您拥有的唯一选项是您设置为的模块独立config.cache_store设置:null_store

  • 正如@ viktor-trón先前所说,在测试之间设置cache_store是不可能的,只能在init。

  • 缓存在默认cache_store环境之间共享。 因此,(i)如果您担心开发会话中的内容,应测试之前清除缓存,(ii)运行测试会清除其他环境的缓存。 但是,您的生产环境应该使用类似mem_cache_store或其他更适合它的东西,所以应该没问题。

从两个第一点来看,似乎不能以每个示例为基础测试低级缓存。