代码之家  ›  专栏  ›  技术社区  ›  DEfusion

在轨道上测试带RSpec的清扫器

  •  2
  • DEfusion  · 技术社区  · 15 年前

    我想确保我的清扫器被适当调用,因此我尝试添加如下内容:

    it "should clear the cache" do
        @foo = Foo.new(@create_params)
        Foo.should_receive(:new).with(@create_params).and_return(@foo)
        FooSweeper.should_receive(:after_save).with(@foo)
        post :create, @create_params
    end
    

    但我只是得到:

    <FooSweeper (class)> expected :after_save with (...) once, but received it 0 times
    

    我曾尝试在测试配置中打开缓存,但没有任何区别。

    3 回复  |  直到 15 年前
        1
  •  3
  •   chug2k Anil Varghese    11 年前

    正如您已经提到的,必须在环境中启用缓存才能使其工作。如果它被禁用,那么我下面的示例将失败。在运行时为缓存规范临时启用此功能可能是一个好主意。

    “after_save”是一个实例方法。您为类方法设置了一个期望,这就是它失败的原因。

    it "should clear the cache" do
      @foo = Foo.new(@create_params)
      Foo.should_receive(:new).with(@create_params).and_return(@foo)
    
      foo_sweeper = mock('FooSweeper')
      foo_sweeper.stub!(:update)
      foo_sweeper.should_receive(:update).with(:after_save, @foo)
    
      Foo.instance_variable_set(:@observer_peers, [foo_sweeper])      
    
      post :create, @create_params
    end
    

    问题是Foo的观察器(sweeper是观察器的一个子类)是在Rails启动时设置的,因此我们必须使用“instance_variable_set”将sweeper mock直接插入到模型中。

        2
  •  2
  •   Mandrake Button    12 年前

    清扫器是单例的,在rspec测试开始时实例化。因此,您可以通过MySweeperClass.instance()访问它。这对我很有用(Rails 3.2):

    require 'spec_helper'
    describe WidgetSweeper do
      it 'should work on create' do
        user1 = FactoryGirl.create(:user)
    
        sweeper = WidgetSweeper.instance
        sweeper.should_receive :after_save
        user1.widgets.create thingie: Faker::Lorem.words.join("")
      end
    end
    
        3
  •  2
  •   Mike    11 年前

    假设你有:

    • A. FooSweeper
    • A. Foo 用一个 bar

    foo_sweeper_spec.rb :

    require 'spec_helper'
    describe FooSweeper do
      describe "expiring the foo cache" do
        let(:foo) { FactoryGirl.create(:foo) }
        let(:sweeper) { FooSweeper.instance }
        it "is expired when a foo is updated" do
          sweeper.should_receive(:after_update)
          foo.update_attribute(:bar, "Test")
        end
      end
    end