【问题标题】:how can I test rails cache feature我如何测试rails缓存功能
【发布时间】:2013-04-15 22:20:04
【问题描述】:

这是我的标签模型,我不知道如何测试 Rails.cache 功能。

class Tag < ActiveRecord::Base
  class << self
    def all_cached
      Rails.cache.fetch("tags.all", :expires_in => 3.hours) do
        Tag.order('name asc').to_a
      end
    end
    def find_cached(id)
      Rails.cache.fetch("tags/#{id}", :expires_in => 3.hours) do
        Tag.find(id)
      end
    end
  end

  attr_accessible :name
  has_friendly_id :name, :use_slug => true, :approximate_ascii => true
  has_many :taggings #, :dependent => :destroy
  has_many :projects, :through => :taggings
end

您知道如何对其进行测试吗?

【问题讨论】:

    标签: ruby-on-rails caching rspec


    【解决方案1】:

    嗯,首先,您不应该真正测试框架。 Rails 的缓存测试表面上为您涵盖了这一点。也就是说,请参阅this answer 以获得您可以使用的小帮手。您的测试将如下所示:

    describe Tag do
      describe "::all_cached" do
        around {|ex| with_caching { ex.run } }
        before { Rails.cache.clear }
    
        context "given that the cache is unpopulated" do
          it "does a database lookup" do
            Tag.should_receive(:order).once.and_return(["tag"])
            Tag.all_cached.should == ["tag"]
          end
        end
    
        context "given that the cache is populated" do
          let!(:first_hit) { Tag.all_cached }
    
          it "does a cache lookup" do
            before do
              Tag.should_not_receive(:order)
              Tag.all_cached.should == first_hit
            end
          end
        end
      end
    end
    

    这实际上并没有检查缓存机制——只是没有调用#fetch 块。它很脆弱,并且与 fetch 块的实现有关,所以要小心,因为它会成为维护债务。

    【讨论】:

    • 您在测试环境中使用的是哪个缓存存储?你在 test.env 中有这个吗? config.cache_store = :memory_store
    • 我认为测试框架完全可以确认它是否按照我理解的方式工作。我可能不清楚这些文档,或者我可能不完全确定我的理解。与 TDD 一样,仅编写测试用例的行为就可以帮助我明确我想要实现的目标。
    【解决方案2】:

    我同意@chris-heald'sanswer。为了让测试不那么脆弱,你可以这样改变你的代码:

    def self.all_cached
      Rails.cache.fetch('tags.all', expires_in: 3.hours) do
        all_uncached
      end
    end
    
    def self.all_uncached
      Tag.order('name asc').to_a
    end
    

    并通过以下方式对其进行测试:

    describe Tag do
      context 'retrieving all tags' do
        let(:tag) { Tag.create! }
        before do
          allow(Tag).to receive(:all_uncached) do
            fail 'Database hit!' if @database_hit
            @database_hit = true
            [tag]
          end
        end
    
        context 'when the cache is populated' do
          before { Tag.all_cached }
    
          it 'should not hit the database' do
            expect(Tag.all_uncached).to raise_error 'Database hit!'
            expect(Tag.all_cached).to eq [tag]
          end
        end
      end
    end
    

    【讨论】:

      猜你喜欢
      • 2011-06-29
      • 2011-02-15
      • 1970-01-01
      • 1970-01-01
      • 2011-04-04
      • 1970-01-01
      • 1970-01-01
      • 2012-05-30
      • 1970-01-01
      相关资源
      最近更新 更多