In my simplified example of what I'm actually doing, let's say I have 2 calls to the database:
Repo.add( something_stringy )
Repo.remove( something_floaty )
and I want to use mocks for the database calls, as the real calls will be tested elsewhere:
let(:repo){
repo = double("Repo")
repo.should_receive(:add).with(instance_of(String))
repo.should_receive(:remove).with(instance_of(Float))
repo
}
before { FakeKlass.const_set :Repo, repo }
that's all fine and dandy, but now if I wrap the calls in a transaction I'm a bit stumped:
Repo.transaction do
# ... some error checking in here somewhere...
Repo.add( something_stringy )
Repo.remove( something_floaty )
end
because if I write a mock that receives transaction
it will receive the call, but everything in the block won't get called, and I get:
expected: 1 time received: 0 times
for all of the other mocks. Would anyone be able to show me how I should be writing my spec to deal with this? I've tried reading the relevant page in the RSpec book on around(:each)
but that was about as clear as mud to me.
Any help is much appreciated.
You can use #and_yield
to yield from an expectation chain:
repo.should_receive( :transaction ).and_yield
You also don't need to set up a double to stub out methods on your Repo class. For example, your setup could be written:
before( :each ) do
Repo.should_receive( :transaction ).and_yield
Repo.should_receive( :add ).with( instance_of(String) )
Repo.should_receive( :remove ).with( instance_of(Float) )
end
You might also consider using stub
instead of should_receive
, as it doesn't set up expectations:
before( :each ) do
Repo.stub( :transaction ).and_yield
Repo.stub( :add )
Repo.stub( :remove )
end
In general, you should only use should_receive
when you want to test the interaction between two objects. My own personal rule of thumb is that if it appears in a before
, use stub
; if it's in an example, especially with a specific value, use should_receive
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With