块实现
当您传递一个块时,RSpec 将使用您的块作为该方法的实现。调用者提供的任何参数(或块)都将传递给您的块实现。此功能极其灵活,支持许多更具声明性的流畅接口不支持的用例。
您可以将块传递给任何流畅接口方法
* `allow(dbl).to receive(:foo) { do_something }`
* `allow(dbl).to receive(:foo).with("args") { do_something }`
* `allow(dbl).to receive(:foo).once { do_something }`
* `allow(dbl).to receive(:foo).ordered { do_something }`
下面显示了一些块实现的更常见用例,但这并不详尽。
使用块以更简洁的语法指定返回值
给定一个名为“returnvaluespec.rb”的文件,其中包含
RSpec.describe "Specifying a return value using a block" do
it "returns the block's return value" do
dbl = double
allow(dbl).to receive(:foo) { 14 }
expect(dbl.foo).to eq(14)
end
end
当我运行 `rspec return_value_spec.rb` 时
那么这些示例应该全部通过。
使用块验证参数
给定一个名为“verifyargumentsspec.rb”的文件,其中包含
RSpec.describe "Verifying arguments using a block" do
it "fails when the arguments do not meet the expectations set in the block" do
dbl = double
allow(dbl).to receive(:foo) do |arg|
expect(arg).to eq("bar")
end
dbl.foo(nil)
end
end
当我运行 `rspec verify_arguments_spec.rb` 时
那么它应该失败,并提示
Failure/Error: expect(arg).to eq("bar")
使用块执行计算
给定一个名为“performcalculationspec.rb”的文件,其中包含
RSpec.describe "Performing a calculation using a block" do
it "returns the block's return value" do
loan = double("Loan", :amount => 100)
allow(loan).to receive(:required_payment_for_rate) do |rate|
loan.amount * rate
end
expect(loan.required_payment_for_rate(0.05)).to eq(5)
expect(loan.required_payment_for_rate(0.1)).to eq(10)
end
end
当我运行 `rspec perform_calculation_spec.rb` 时
那么这些示例应该全部通过。
生成给调用者的块
给定一个名为“yieldtocaller_spec.rb”的文件,其中包含
RSpec.describe "When the caller passes a block" do
it "can be yielded to from your implementation block" do
dbl = double
allow(dbl).to receive(:foo) { |&block| block.call(14) }
expect { |probe| dbl.foo(&probe) }.to yield_with_args(14)
end
end
当我运行 `rspec yield_to_caller_spec.rb` 时
那么这些示例应该全部通过。
在块中委托给部分替身的原始实现
给定一个名为“delegatetooriginal_spec.rb”的文件,其中包含
class Calculator
def self.add(x, y)
x + y
end
end
RSpec.describe "When using a block implementation on a partial double" do
it "supports delegating to the original implementation" do
original_add = Calculator.method(:add)
allow(Calculator).to receive(:add) do |x, y|
original_add.call(x, y) * 2
end
expect(Calculator.add(2, 5)).to eq(14)
end
end
当我运行 `rspec delegate_to_original_spec.rb` 时
那么这些示例应该全部通过。
模拟瞬态网络故障
给定一个名为“simulatetransientnetworkfailurespec.rb”的文件,其中包含
RSpec.describe "An HTTP API client" do
it "can simulate transient network failures" do
client = double("MyHTTPClient")
call_count = 0
allow(client).to receive(:fetch_data) do
call_count += 1
call_count.odd? ? raise("timeout") : { :count => 15 }
end
expect { client.fetch_data }.to raise_error("timeout")
expect(client.fetch_data).to eq(:count => 15)
expect { client.fetch_data }.to raise_error("timeout")
expect(client.fetch_data).to eq(:count => 15)
end
end
当我运行 `rspec simulate_transient_network_failure_spec.rb` 时
那么这些示例应该全部通过。