In writing Rspec tests, I’m often frustrated with should_receive. I’d like to know if there’s a less intrusive alternative.
For example:
describe "making a cake" do
it "should use some other methods" do
@baker.should_receive(:make_batter)
@baker.make_cake
end
end
The call to should_receive is a good description, but it breaks my code, because should_receive works by masking the original method, and make_cake can’t proceed unless make_batter actually returns some batter. So I change it to this:
@baker.should_receive(:make_batter).and_return(@batter)
This is ugly because:
- It looks like I’m testing that
make_battercorrectly returns@batter, but I’m actually forcing the fake version ofmake_batterto return that. - It forces me to separately set up
@batter - If
make_batterhas any important side effects (which could be a code smell, I suppose) I have to make those happen, too.
I wish that should_receive(:make_batter) would verify the method call and pass it on to the original method. If I wanted to stub its behavior for better isolation testing, I would do so explicitly: @baker.stub(:make_batter).and_return(@batter).
Is there a way to do something like should_receive without preventing the original method call? Is my problem a symptom of bad design?
It looks like the nicer API to delegate to the original method that Myron Marston alluded to has actually been added in rspec-mocks v2.12.0
and_call_originalwhich delegates to the original method.So now you can simply do this any time you “want to set a message expecation without interfering with how the object responds to the message”:
Thanks for adding this, Myron.