在 Rails 中使用 RSpec 测试扫地机

发布于 2024-07-13 20:58:44 字数 449 浏览 11 评论 0原文

我想确保我的清扫器被适当地调用,所以我尝试添加这样的内容:

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

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

I want to make sure my sweeper is being called as appropriate so I tried adding something like this:

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

But I just get:

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

I've tried turning on caching in the test config but that didn't make any difference.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一抹微笑 2024-07-20 20:58:45

假设您有:

  • 一个 FooSweeper
  • 一个带有 bar 属性

foo_sweeper_spec.rbFoo 类:

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

Assuming you have:

  • a FooSweeper class
  • a Foo class with a bar attribute

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
太阳男子 2024-07-20 20:58:44

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

'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 的观察者(扫描器是观察者的子类)在 Rails 启动时设置,因此我们必须使用 ' 将扫描器模拟直接插入模型中实例变量集'。

As you already mentioned caching has to be enabled in the environment for this to work. If it's disabled then my example below will fail. It's probably a good idea to temporarily enable this at runtime for your caching specs.

'after_save' is an instance method. You setup an expectation for a class method, which is why it's failing.

The following is the best way I've found to set this expectation:

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

The problem is that Foo's observers (sweepers are a subclass of observers) are set when Rails boots up, so we have to insert our sweeper mock directly into the model with 'instance_variable_set'.

別甾虛僞 2024-07-20 20:58:44

Sweeper 是 Singleton,在 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

Sweepers are Singletons and are instantiated at the beginning of the rspec test. As such you can get to it via MySweeperClass.instance(). This worked for me (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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文