6

这是我的标签模型,我不知道如何测试 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

你知道如何测试它吗?

4

2 回答 2

8

好吧,首先,您不应该真正测试框架。Rails 的缓存测试表面上为您涵盖了这一点。也就是说,请参阅此答案以获取您可以使用的小帮手。然后,您的测试将类似于:

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 块的实现有关,所以要小心,因为它会成为维护债务。

于 2013-04-22T21:44:06.437 回答
0

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

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
于 2019-12-04T14:03:26.033 回答