如何测试 "dereferenced" lambda 是否传递给方法?

How can I test that a "dereferenced" lambda is passed to a method?

考虑这段代码:

def thing_incrementer
  lambda do
    self.foo +=1
    save!
  end
end

def increment_thing
  with_lock &thing_incrementer
end

如何编写测试 thing_incrementerwith_lock 作为一个块传递的测试?如果我只是想测试它是否作为参数传递(没有前导 &),我会这样做:

let(:the_lambda){ lambda{} }
x.stub(:thing_incrementer){ the_lambda }
x.should_receive(:with_lock).with(the_lambda)
x.increment_thing

传递 &thing_incrementer 传递一个作为块绑定到 with_thing 的过程。所以,只需测试一下:

expect(subject).to receive(:with_lock).with(no_args) do |&blk|
  expect(blk).to be_a(Proc)
end

如果你想传递一个 lambda 作为参数,那么你不会在它前面加上 & 并且它只会作为一个普通参数传递,但是你必须调用 blk.call(或其他)而不是屈服于障碍。

检查您是否收到所需的 lambda:

class Foo
  def incrementor
    -> {}
  end

  def increment
    with_lock &incrementor
  end

  def with_lock
    yield
  end
end

describe "Lock" do
  subject { Foo.new }
  let(:the_lambda) { -> {} }
  before do
    expect(subject).to receive(:incrementor).and_return(the_lambda)
  end

  it "should receive the_lambda from the incrementor" do
    expect(subject).to receive(:with_lock).with(no_args) do |&blk|
      expect(blk).to eq(the_lambda)
    end
    subject.increment
  end
end