【问题标题】:Test if a block is passed with RSpec Mocks使用 RSpec Mocks 测试一个块是否通过
【发布时间】:2014-12-02 07:31:17
【问题描述】:

我可以测试参数是否传递如下:

RSpec.describe do
  it do
    obj = double
    expect(obj).to receive(:method).with(1, 2, 3)
    obj.method(1, 2, 3)
  end
end

我应该如何处理块参数?我的理想代码:

RSpec.describe do
  it do
    obj = double
    proc = Proc.new{}
    expect(obj).to receive(:method).with(1, 2, 3).with_block(proc)
    obj.method(1, 2, 3, &proc)
  end
end

【问题讨论】:

标签: ruby rspec rspec3


【解决方案1】:

似乎我不能简单地测试一个块是否通过方法链接传递。我找到了一个枯燥的答案,块实现:

RSpec.describe do
  it do
    obj = double
    proc = Proc.new{}
    expect(obj).to receive(:method).with(1, 2, 3) do |*args, &block|
      expect(proc).to be(block)
    end
    obj.method(1, 2, 3, &proc)
  end
end

但是,我们不能像receive(:method).with(1, 2, 3){|*| ...}.and_call_original那样同时使用块实现和其他响应配置方法。

【讨论】:

  • 我想知道您是否可以通过在块实现中使用super(*args, &block) 来模拟.and_call_original....
  • RSpec 应该返回 do 块中的最后一条语句:
【解决方案2】:

根据上面的 git ticket,你可以通过

expect(object)
  .to receive(:method)
  .with(param1, param2) do |&block|
    expect(block).to be('my block contents')
  end
  .and_call_original

这将验证参数是否传递并评估块内容。然后你可以链接.and_mock_original.and_call_original等。

【讨论】:

    【解决方案3】:

    您不能使用期望来测试特定块是否通过。您可以通过在其中添加代码来检查代码是否运行,例如:

    RSpec.describe do
      it do
        obj = double
        block_is = double('block')
        block = -> {
          block_is.run
        }
    
        expect(obj).to receive(:method).with(1, 2, 3).and_yield
        expect(block_is).to receive(:run)
    
        obj.method(1, 2, 3, &block)
      end
    end
    

    【讨论】:

    • 嗯,我刚刚可以使用:allow(obj).to receive(:method).with(1, 2, 3, &a_proc).and_return(a_value)。它按预期工作.. 编辑:嗯,rspec 只是忽略了块)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-04
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 2015-03-19
    • 1970-01-01
    相关资源
    最近更新 更多