I feel like this is a not-so-much documented topic, at least I've had a lot of trouble finding our about the best practices here.
I'm fragment caching in the view using a cache_key:
%tbody
- @employees.each do |employee|
- cache employee do
%tr[employee]
%td= employee.name
%td= employee.current_positions
%td= employee.home_base
%td= employee.job_classes
Now I can add :touch => true on the :belongs_to side of my has_many associations and this will do everything I need to keep this fragment caching up to date, but for the life of me I'm having a hard time figuring out how to test this.
Dropping in :touch => true is easy and convenient but it spreads the expiry logic around a couple places. I'd love to have an RSpec request spec that walks through and checks the behavior on this, something that isn't liable to change much but can bring all the caching requirements into one specific file that describes what is supposed to be occurring.
I tried along these lines:
require 'spec_helper'
include AuthenticationMacros
describe "Employee index caching" do
before do
Rails.cache.clear
ActionController::Base.perform_caching = true
login_confirmed_employee
end
after do
ActionController::Base.perform_caching = false
end
specify "the employee cache is cleared when position assignments are modified"
specify "the employee cache is cleared when home base assignments are modified"
end
The specs were fleshed out with the Capybara steps of going through and making the updates of course, and I thought I was quite on the right track. But the tests were flickering in weird ways. I would modify the specs to output the employee objects cache_key, and sometimes the cache_keys would change and sometimes not, sometimes the specs would pass and sometimes not.
Is this even a good approach?
I know SO wants questions that are answerable, so to start: how can I set up and tear down this test to use caching, when my test env does not have caching on by default? In general, however, I'd really like to hear how you might be successfully testing fragment caching in your apps if you have had success with this.
EDIT
I'm accepting cailinanne's answer as it addresses the problem that I specifically ask about, but I have decided however that I don't even recommend integration testing caching if you can get away from it.
Instead of specifying touch in my association declarations, I've created an observer specific to my caching needs that touches models directly, and am testing it in isolation.
I'd recommend if testing a mulit-model observer in isolation to also include a test to check the observers observed_models, otherwise you can stub out too much of reality.
The particular answer that lead me to this is here: https://stackoverflow.com/a/33869/717365
Let me first say that in this answer, you may get more sympathy then fact. I've been struggling with these same issues. While I was able to get reproducible results for a particular test, I found that the results varied according to whether or not I ran one versus multiple specs, and within or without spork. Sigh.
In the end, I found that 99.9% of my issues disappeared if I simply enabled caching in my test.rb file. That might sound odd, but after some thought it was "correct" for my application. The great majority of my tests are not at the view/request layer, and for the few that are, doesn't it make sense to test under the same configurations that the user views?
While I was wrestling with this, I wrote a blog post that contains some useful test helpers for testing caching. You might find it useful.
Here is what I've used in my specs with caching enabled in my config/environments/test.rb
require 'spec_helper'
include ActionController::Caching::Fragments
describe 'something/index.html.erb' do
before(:each) do
Rails.cache.clear
render
end
it 'should cache my fragment example' do
cached_fragment = Rails.cache.read(fragment_cache_key(['x', 'y', 'z']))
cached_fragment.should have_selector("h1")
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With