生成

使用 and_yield 使测试替身在接收到消息时生成提供的参数。如果调用者没有提供块,或者调用者的块不接受提供的参数,则会引发错误。如果你想多次生成,请将多个 and_yield 调用链接在一起。

生成一个参数

给定一个名为“yieldargumentsspec.rb”的文件,其中包含

RSpec.describe "Making it yield arguments" do
  it "yields the provided args" do
    dbl = double
    allow(dbl).to receive(:foo).and_yield(2, 3)

    x = y = nil
    dbl.foo { |a, b| x, y = a, b }
    expect(x).to eq(2)
    expect(y).to eq(3)
  end
end

我运行 rspec yield_arguments_spec.rb

那么示例应该全部通过。

当调用者没有提供块时,它会失败

给定一个名为“nocallerblock_spec.rb”的文件,其中包含

RSpec.describe "Making it yield" do
  it "fails when the caller does not provide a block" do
    dbl = double
    allow(dbl).to receive(:foo).and_yield(2, 3)
    dbl.foo
  end
end

我运行 rspec no_caller_block_spec.rb

那么它应该失败,并显示

#<Double (anonymous)> asked to yield |[2, 3]| but no block was passed

当调用者的块不接受提供的参数时,它会失败

给定一个名为“argmismatchspec.rb”的文件,其中包含

RSpec.describe "Making it yield" do
  it "fails when the caller's block does not accept the provided arguments" do
    dbl = double
    allow(dbl).to receive(:foo).and_yield(2, 3)
    dbl.foo { |x| }
  end
end

我运行 rspec arg_mismatch_spec.rb

那么它应该失败,并显示

#<Double (anonymous)> yielded |2, 3| to block with arity of 1

多次生成

给定一个名为“yieldmultipletimes_spec.rb”的文件,其中包含

RSpec.describe "Making it yield multiple times" do
  it "yields the specified args in succession" do
    yielded = []

    dbl = double
    allow(dbl).to receive(:foo).and_yield(1).and_yield(2).and_yield(3)
    dbl.foo { |x| yielded << x }

    expect(yielded).to eq([1, 2, 3])
  end
end

我运行 rspec yield_multiple_times_spec.rb

那么示例应该全部通过。