【问题标题】:Rspec: How to test recursion?Rspec:如何测试递归?
【发布时间】:2010-09-01 20:19:28
【问题描述】:

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

我的做法:

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

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

【问题讨论】:

    标签: ruby recursion mocking rspec


    【解决方案1】:

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

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

    【讨论】:

    • 啊,好吧。那好吧!我试图找到一个错误 - 该方法确实返回了错误的值(它比这里描述的更复杂)。我想我可以测试它的每个部分以缩小问题空间。每个级别的递归都变得更加复杂,测试递归是否正确执行会很好。
    • 换句话说:不测试实现,测试代码的效果。很好的答案!
    【解决方案2】:

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

    但有时您只需要对递归添加一些基本检查即可。 你可以用 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,存根方法(包含测试检查)也将调用原始方法实现,这将按预期执行递归。

    【讨论】:

      猜你喜欢
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      相关资源
      最近更新 更多