如何在不同实例上测试具有不同参数的相同方法的接收

时间:2017-07-20 07:38:02

标签: ruby-on-rails ruby unit-testing rspec

我有像

这样的方法
def my_method
  MyClass.new.track(arg1, arg2)

  if satisfies_some_condition
    2.times { MyClass.new.track(arg3, arg4) }
  end
end

RSpec中,我想测试#track

的收据
expect_any_instance_of(MyClass).to receive(:track).with(arg1, arg2)
expect_any_instance_of(MyClass).to receive(:track).with(arg3, arg4).twice

但我收到此错误

  

消息&#39;跟踪&#39;是#<MyClass:70362069595680 >收到的,但有   已被#<MyClass:0x007ffce788e460>

收到

似乎here它建议通过升级到RSpec-mocks v3.6.0来解决这个问题但是即使将RSpec-mocks gem升级为{{1}后我仍然会遇到同样的错误}}

1 个答案:

答案 0 :(得分:0)

我从来没有喜欢any_instance所以不确定如何用它做你想要的东西,然而,一个可能做你想要的东西的替代方案就像是

class MyClass
  def track(a, b)
  end
end

def my_method(pass = true)
  MyClass.new.track('a', 'b')

  if pass
    2.times { MyClass.new.track('c', 'd') }
  end
end

RSpec.describe "SO question" do
  it 'pass' do
    first = double(MyClass)
    expect(first).to receive(:track).with('a', 'b')
    second = double(MyClass)
    expect(second).to receive(:track).with('c', 'd').twice

    allow(MyClass).to receive(:new).and_return(first, second)
    my_method
  end

  it 'fail' do
    first = double(MyClass)
    expect(first).to receive(:track).with('a', 'b')
    second = double(MyClass)
    expect(second).to receive(:track).with('c', 'd').twice

    allow(MyClass).to receive(:new).and_return(first, second)
    my_method(false)
  end
end

更加冗长,但强制new方法返回多个对它们有期望的实例。 and_return将在每次调用时按顺序返回这些值,然后将继续返回任何其他调用的最后一个值。