Rspec:如何测试递归?

发布于 2024-09-17 12:34:33 字数 466 浏览 4 评论 0 原文

我想测试是否使用特定参数递归调用方法。

我的方法:

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

出乎意料的是,RSpec 失败了:

expected :rec with (7) once, but received it 0 times

知道我的方法有什么问题吗?如何使用特定参数测试有效递归?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

混吃等死 2024-09-24 12:34:34

现在测试的问题在于,您正在放弃尝试测试的方法。 r.should_receive(:rec) 正在用存根替换 r#rec,这当然不会调用 r.rec(7)

更好的方法是简单地测试初始方法调用的结果是否正确。该方法是否递归、迭代或给朋友打电话并不重要,只要它最终给出正确的答案即可。

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.

数理化全能战士 2024-09-24 12:34:34

通常,如果您需要测试递归,那就是代码味道;您可能应该将该方法拆分为不同的职责或其他内容。

但有时您只需要对递归添加一些基本检查。
您可以使用 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

通常 should_receive 只会存根真正的方法,这就是递归不起作用的原因。使用and_call_original,存根方法(包含测试检查)还将调用原始方法实现,该实现将按预期执行递归。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文