目前,如果您有一个多次调用的方法,并且您希望确保发生某个调用,那么您需要编写大量虚拟代码。
events = []
Analytics.should_receive(:track) do |event|
events << event
end.any_number_of_times
<<INVOKE CONTROLLER ACTION>>
event = events.find{|event| event.event_name == 'MyEventName'}
event.should_not be_nil
event.properties.should include({ property_a: value})
需要上面的代码 1.记录被跟踪的所有事件 2.找到特定事件名称的至少一个实例并匹配属性
当应该采用更简单的方法时,会产生大量代码。
Analytics.should_receive(:track) do |event|
expect(event.event_name).to eq('MyEventName')
expect(event.properties).to include({ property_a: value})
end.at_least(:once)
不幸的是,只有在第一次调用Analytics.track导致匹配时,上述操作才有效。如果是第二次调用,则此测试将失败。
我有自己的解决方案试图让它变得通用且可重复使用但我想知道是否有一种简单的方法可以实现这一点,我可能会失踪。
答案 0 :(得分:1)
您可以尝试将预期的确切事件传递给with
。这里的关键是在调用track
之前存根should_receive
。
这是一个示例代码:
require 'ostruct'
class Analytics
def self.run
track(OpenStruct.new(event_name: 'test1', properties: { a: '1' }))
track(OpenStruct.new(event_name: 'test2', properties: { a: '2' }))
end
def self.track(event)
end
end
describe Analytics do
it 'verifies the second event' do
expected_event = OpenStruct.new(event_name: 'test2', properties: { a: '2' })
Analytics.stub(:track)
Analytics.should_receive(:track).with(expected_event)
Analytics.run
end
end
答案 1 :(得分:1)
OP应该“接受”前面的答案,因为它包含两个关键元素并且首先出现,但是这里有一个更简洁的例子(它也使用了最新的expect
方法),以防它有助于使rspec的能力更加清晰:
describe "unordered checks" do
it 'verifies the second method call' do
obj = Object.new
obj.stub(:track)
expect(obj).to receive(:track).with('expected')
obj.track('unexpected')
obj.track('expected')
end
end
我会把这个编辑成上一个答案,但认为这会占用过多的许可证。