TDD、Ruby和;处理零参数

TDD、Ruby和;处理零参数,ruby,tdd,Ruby,Tdd,TDD实践的一部分涉及从边缘进入核心功能,并从测试最简单的退化情况开始。我在Ruby中工作,所以我经常发现自己在编写这样的测试: it "does the thing if given nil" do expect { my_method(nil) }.to do_the_thing end def my_method(arg) if arg.nil? do_the_thing return end do_the_real_thing end 生产代码如下:

TDD实践的一部分涉及从边缘进入核心功能,并从测试最简单的退化情况开始。我在Ruby中工作,所以我经常发现自己在编写这样的测试:

it "does the thing if given nil" do
  expect { my_method(nil) }.to do_the_thing
end
def my_method(arg)
  if arg.nil?
    do_the_thing
    return
  end

  do_the_real_thing
end
生产代码如下:

it "does the thing if given nil" do
  expect { my_method(nil) }.to do_the_thing
end
def my_method(arg)
  if arg.nil?
    do_the_thing
    return
  end

  do_the_real_thing
end
我不喜欢在每个公共方法中都乱扔这样的保护条款,但是考虑到Ruby的动态特性,你的底线在哪里?什么时候将传递有效参数的责任放在调用代码上是合理的

我想写一些有重点的、有表现力的方法,这些方法不会充斥着过度防御的代码,但我也想构建一个健壮的、正确的系统


从边缘案例中放松的做法对我很有吸引力,但我经常不确定应该如何处理这个特殊的边缘案例。

我认为编写代码的防御方式取决于错误条件的情况是否合理

你问自己的问题是,假设这种情况会在正常事件过程中发生,这有多合理

如果在正常的事件过程中可能发生错误是合理的,那么相应地进行编码是有意义的

如果在正常的事件过程中,错误条件不应该发生,那么我就不会设置检查条件。如果出现错误情况,最好让应用程序抛出致命错误并停止工作,因为存在根本错误

例如,假设您有一个方法,该方法接受从表单中预定义列表中选择的国家名称作为参数。该方法有理由假定它将获得一个有效的国家名称。该方法没有理由对此进行健全性检查(例如检查不是有效国家名称的字符串)

在另一个示例中,假设您有一个方法处理来自已知数据质量较差的数据库源的参数。在这种情况下,检查以确保参数符合方法的预期是合理的


编写过度防御的代码实际上可能会隐藏一些问题。我见过编写的代码检查完全不合理的事情,记录问题,然后继续运行。这些应用程序通常具有不可预测的行为,因为它们隐藏了真正应该处理的编码问题。

@sawa我的问题是关于测试驱动的设计的一个方面。您可以使用参数的默认值吗?这可能有助于避免将
nil
传递给method如果您有许多类似的防御代码段,可能您错过了TDD的重构部分。@WandMaker如果调用方完全忽略参数,则默认参数值将起作用,但我考虑的是显式传递nil的情况,在这种情况下,默认值将被覆盖。