可选地在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
感谢罗斯蒂,但是
- 需要在示例之间清除缓存
- 缓存存储不能在示例上设置不同,只有在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
或其他更适合它的东西,所以应该没问题。
从两个第一点来看,似乎不能以每个示例为基础测试低级缓存。