开发者

Rspec: How to test recursion?

开发者 https://www.devze.com 2023-01-14 06:14 出处:网络
I\'d like to test that a method is called recursively with a specific argument. My app开发者_JAVA技巧roach:

I'd like to test that a method is called recursively with a specific argument.

My app开发者_JAVA技巧roach:

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消