Is there a less intrusive alternative to Rspec's `should_receive`?

rspec, ruby

Solution

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

- Add `and_call_original` which 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":

@baker.should_receive(:make_batter).and_call_original

Thanks for adding this, Myron.

Problem

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_batter` correctly returns `@batter`, but I'm actually forcing the fake version of `make_batter` to return that. - It forces me to separately set up `@batter` - If `make_batter` has 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?

Original source