How to: Rails cache for individual rspec tests

Updated . Posted . Visible to the public.

Rails default config uses the ActiveSupport::Cache::NullStore and disables controller caching Show archive.org snapshot for all environments except production:

config.action_controller.perform_caching = false
config.cache_store = :null_store

If you want to test caching you have at least two possibilities:

  1. Enable caching for every test (not covered by this card and straightforward)
  2. Enable caching for individual test

Enable caching for individual test (file cache)

1. Leave the default configuration
2. Add a caching helper which gives you a unique file caching path for parallel tests:

module CachingHelpers
  def file_caching_path
    path = "tmp/test#{ENV['TEST_ENV_NUMBER']}/cache"
    FileUtils::mkdir_p(path)

    path
  end
end

RSpec.configure do |config|
  config.include CachingHelpers
end

3. Now stub the Rails cache and clear it before each example:

RSpec.describe SomeClass
  let(:file_cache) { ActiveSupport::Cache.lookup_store(:file_store, file_caching_path) }
  let(:cache) { Rails.cache }
  
  before do
    allow(Rails).to receive(:cache).and_return(file_cache)
    Rails.cache.clear
  end
  
  it do
    expect(cache.exist?('some_key')).to be(false)
    
    cache.write('some_key', 'test')
    
    expect(cache.exist?('some_key')).to be(true)
  end
end

Enable caching for individual test (memory store)

1. Leave the default configuration
2. Now stub the Rails cache and clear it before each example:

RSpec.describe SomeClass
  # memory store is per process and therefore no conflicts in parallel tests
  let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) } 
  let(:cache) { Rails.cache }
  
  before do
    allow(Rails).to receive(:cache).and_return(memory_store)
    Rails.cache.clear
  end
  
  it do
    expect(cache.exist?('some_key')).to be(false)
    
    cache.write('some_key', 'test')
    
    expect(cache.exist?('some_key')).to be(true)
  end
end
Last edit
Emanuel
License
Source code in this card is licensed under the MIT License.
Posted by Emanuel to makandra dev (2017-06-27 10:14)