所以基于我的理解,当你做的时候,我相信
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)
我对PingTwitter
和PingPinterest
进行了同样的测试。
我在第二次和第三次期望中失败,因为看起来测试实际上在所有resque作业运行之前完成了。只有第一次测试才真正通过。 RSpec然后抛出MockExpectationError
告诉我Rails.logger
没有收到.info
其他两个测试。以前有人有这方面的经验吗?
有人提到should_receive
的行为与mock
相似,我应该.exactly(n).times
。很抱歉没有提前说清楚,但我在不同的it
块中有我的期望,我不认为一个should_receive
块中的it
会为下一个{{1}模拟它阻止?如果我对此错了,请告诉我。
答案 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