To add a collaborator to this project you will need to use the Relish gem to add the collaborator via a terminal command. Soon you'll be able to also add collaborators here!
More about adding a collaboratorBlock implementation
When you pass a block, RSpec will use your block as the implementation of the method. Any
arguments (or a block) provided by the caller will be yielded to your block implementation.
This feature is extremely flexible, and supports many use cases that are not directly
supported by the more declaritive fluent interface.
You can pass a block to any of the fluent interface methods:
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 }
Some of the more common use cases for block implementations are shown below, but this
is not an exhaustive list.
- Scenarios
-
- Use a block to specify a return value with a terser syntax
- Use a block to verify arguments
- Use a block to perform a calculation
- Yield to the caller's block
- Delegate to partial double's original implementation within the block
- Simulating a transient network failure
- Use a block to specify a return value with a terser syntax
-
- Given
-
a file named "return_value_spec.rb" with:
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
- When
-
I run
rspec return_value_spec.rb
- Then
- the examples should all pass
- Use a block to verify arguments
-
- Given
-
a file named "verify_arguments_spec.rb" with:
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
- When
-
I run
rspec verify_arguments_spec.rb
- Then
-
it should fail with:
Failure/Error: expect(arg).to eq("bar")
- Use a block to perform a calculation
-
- Given
-
a file named "perform_calculation_spec.rb" with:
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
- When
-
I run
rspec perform_calculation_spec.rb
- Then
- the examples should all pass
- Yield to the caller's block
-
- Given
-
a file named "yield_to_caller_spec.rb" with:
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
- When
-
I run
rspec yield_to_caller_spec.rb
- Then
- the examples should all pass
- Delegate to partial double's original implementation within the block
-
- Given
-
a file named "delegate_to_original_spec.rb" with:
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
- When
-
I run
rspec delegate_to_original_spec.rb
- Then
- the examples should all pass
- Simulating a transient network failure
-
- Given
-
a file named "simulate_transient_network_failure_spec.rb" with:
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
- When
-
I run
rspec simulate_transient_network_failure_spec.rb
- Then
- the examples should all pass
Last published about 2 years ago by Jon Rowe.