I'd like to test that a method is called recursively with a specific argument.
My approach:
class Recursable
def rec(arg)
rec(7) unless arg == 7
end
end
describe Recursable do
it "should recurse" do
r = Recursable.new('test')
r.should_receive(:rec).with(0).ordered
r.should_receive(:rec).with(7).ordered
r.rec(0)
end
end
Unexpectedly, RSpec fails with:
expected :rec with (7) once, but received it 0 times
Any idea what's wrong with my approach? How to test for effective recursion with a specific argument?
The problem with your test as it is now is that you are stubbing away the method you are trying to test. r.should_receive(:rec)
is replacing r#rec
with a stub, which of course doesn't ever call r.rec(7)
.
A better approach would be to simply test that the result of the initial method call is correct. It shouldn't strictly matter whether or not the method recurses, iterates, or phones a friend, as long as it gives the right answer in the end.
Often if you need to test recursion it is a code smell; you probably should split the method into different responsibilities or something.
But some times you just need to add some basic checks on your recursion.
You can do it with Rspec and_call_original
:
it "should recurse" do
r = Recursable.new('test')
r.should_receive(:rec).with(0).ordered.and_call_original
r.should_receive(:rec).with(7).ordered.and_call_original
r.rec(0)
end
Normally should_receive
will just stub the real method, that's why the recursion doesn't work. With and_call_original
the stubbed method (that contains the test checks) will also call the original method implementation, that will perform the recursion as expected.
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