0

目前,如果您有一个被多次调用的方法,并且您想确保发生某个调用,那么您需要编写大量的虚拟代码。

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 导致匹配时,上述方法才有效。如果是第二次调用,此测试将失败。

我有自己的解决方案来尝试使其通用和可重用,但我想知道是否有一种简单的方法可以实现这一点,我可能会错过。

4

2 回答 2

1

您可以尝试传递您期望的确切事件withtrack这里的关键是在调用之前存根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
于 2013-07-05T20:46:41.637 回答
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

我会将此编辑到上一个答案中,但认为这会占用太多许可。

于 2013-07-05T22:52:16.490 回答