如何从should_receive块返回接收者实例的self

时间:2012-11-25 13:35:32

标签: ruby rspec2

我想让一个类的实例方法返回self,并使用另一个类实例self进行初始化 然而,我很难看到如何规范这个问题:

::Api.should_receive(:new).once do |arg|
  arg.should be_an_instance_of(::Cli)
end

运行此规范时,这可确保调用下一个方法,而不是按预期调用Api实例,即块的返回值。例如:

class Cli
  def eg
    api = Api.new(self)
    api.blowup # undefined method for true
  end
end

我真的很喜欢该块返回Api实例self而不调用规范中对Api.new(...)的另一个调用,下面的示例执行此操作并且在我看来非rspec读者会想知道为什么规范通过当明确Api.new(...)被多次调用时。

有谁能建议如何最好地做到这一点?

当前解决方案: 类似::Api.new(...)的内容称为三次:一次创建api,一次创建cli,一次创建start。然而,一个电话的规格通过了。我理解为什么这是正确的,所以不是一个错误。但是,我想要一个不熟悉rspec的读者可以扫描的规范,并且不会产生Api.new不止一次被调用的印象。另请注意,...once.and_return(api){...}不起作用,块需要返回api才能通过。

let(:cli){ ::Cli.start(['install']) }
let(:start){ ::Cli.start(['install']) }
it 'is the API' do
  api = ::Api.new(cli)
  ::Api.should_receive(:new).once do |arg|
    arg.should be_an_instance_of(::Cli)
    api
  end
  start
end

1 个答案:

答案 0 :(得分:1)

您可以将原始方法(new)保存在局部变量中,然后使用它从块中返回新的api

original_method = ::Api.method(:new)
::Api.should_receive(:new).once do |arg|
  arg.should be_an_instance_of(::Cli)
  original_method.call(arg)
end

这将运行期望,检查参数是::Cli的实例,然后从原始方法(即api)返回值。