设置resque .perform方法的期望值。任务在回调中排队

时间:2012-08-27 21:40:40

标签: ruby-on-rails rspec resque resque-retry

所以基于我的理解,当你做的时候,我相信

Resque.inline = Rails.env.test?

您的resque任务将同步运行。我正在编写一个关于resque任务的测试,该测试在after_commit回调期间被排队。

after_commit :enqueue_several_jobs

#class PingsEvent < ActiveRecord::Base
...
   def enqueue_several_jobs
      Resque.enqueue(PingFacebook, self.id)
      Resque.enqueue(PingTwitter, self.id)
      Resque.enqueue(PingPinterest, self.id)
   end

在我的Resque任务类的.perform方法中,我正在做Rails.logger.info,在我的测试中,我正在做类似的事情

..
Rails.logger.should_receive(:info).with("PingFacebook sent with id #{dummy_event.id}")
PingsEvent.create(params)

我对PingTwitterPingPinterest进行了同样的测试。

我在第二次和第三次期望中失败,因为看起来测试实际上在所有resque作业运行之前完成了。只有第一次测试才真正通过。 RSpec然后抛出MockExpectationError告诉我Rails.logger没有收到.info其他两个测试。以前有人有这方面的经验吗?

修改

有人提到should_receive的行为与mock相似,我应该.exactly(n).times。很抱歉没有提前说清楚,但我在不同的it块中有我的期望,我不认为一个should_receive块中的it会为下一个{{1}模拟它阻止?如果我对此错了,请告诉我。

2 个答案:

答案 0 :(得分:2)

class A
  def bar(arg)
  end

  def foo
    bar("baz")
    bar("quux")
  end
end

describe "A" do
  let(:a) { A.new }

  it "Example 1" do
    a.should_receive(:bar).with("baz")
    a.foo # fails 'undefined method bar'
  end
  it "Example 2" do
    a.should_receive(:bar).with("quux")
    a.foo # fails 'received :bar with unexpected arguments
  end
  it "Example 3" do
    a.should_receive(:bar).with("baz")
    a.should_receive(:bar).with("quux")
    a.foo # passes
  end
  it "Example 4" do
    a.should_receive(:bar).with(any_args()).once
    a.should_receive(:bar).with("quux")
    a.foo # passes
  end
end

与存根一样,消息期望取代方法的实现。在满足期望之后,对象将不再响应方法调用 - 这导致'未定义的方法'(如示例1中所示)。

示例2显示了由于参数不正确而期望失败时会发生什么。

示例3显示了如何对同一方法的多个调用进行存根 - 使用正确的参数按接收顺序存根每个调用。

示例4显示您可以使用any_args()帮助程序稍微减少此耦合。

答案 1 :(得分:1)

使用should_receive就像模拟一样。对具有不同参数的同一对象有多个期望是行不通的。如果您将期望值更改为Rails.logger.should_receive(:info).exactly(3).times,您的规范可能会过去。

所有这一切,你可能想要声明一些比这些规范记录的内容更相关的东西,然后你就可以有多个目标期望。

Rails.logger不会在规格之间被拆除,所以如果期望在不同的例子中并不重要。为两个单独的示例吐出记录器的对象ID说明了这一点:

it 'does not tear down rails logger' do
  puts Rails.logger.object_id # 70362221063740
end

it 'really does not' do
  puts Rails.logger.object_id # 70362221063740
end