我有两个功能,foo
和bar
。
function foo() {
if (arguments.length !== 1) {
throw new TypeError('only one argument expected');
}
do work;
}
function bar() {
if (arguments.length !== 3) {
throw new TypeError('exactly three arguments expected');
}
do work;
}
这些功能是根据TDD创建的 - 例如首先编写测试,然后实现函数以使测试通过。测试清单:
foo()
已定义foo()
正常工作foo()
会抛出TypeError
bar()
已定义bar()
正常工作bar()
会抛出TypeError
如您所见,这些函数都具有重复功能 - 它们正在测试每个参数的正确性。由于这个检查在我的函数中非常常见,并且可能会更复杂(检查参数计数是否在某个范围内,检查参数类型等),我已经决定将它移到单独的装饰器函数{{1 }}
所以我为check
编写了测试并实现了check
。
现在重构步骤 - 我利用了check
,所以函数现在看起来如下:
check
我现在应该做什么来检查foo = check(1, function() {
do work;
});
bar = check(3, function() {
do work;
});
和foo()
检查正确数量的参数?我可以放下它们吗?
当我实现函数bar()
时,它立即使用buzz()
(因为它现在被用作定义函数的方式),我是否必须为它编写测试以获取正确数量的参数?我犹豫了,因为这个测试总是绿色的,因为所有的工作都是在装饰器里完成的,所以有没有需要测试?
答案 0 :(得分:1)
我会避免让多个单元测试检查相同的代码,因为将来会:
check
功能,则必须更改2个测试而不是1个。check
,您将会遇到两次失败:一次是foo
,另一次是bar
,而且可能并不明显check
功能。所以,我只保留一组测试,明确命名为check
函数的测试,更好的是,不要使用程序函数来测试它们(不是foo
在你的例子中bar
但是使用仅用于测试目的的假函数。
通过这种方式,您可以在以后更改foo
或bar
以使用,例如check2函数,而无需检查函数的中断测试
根据我的说法,这是最好的理论方法,但要务实:如果你不希望在你的很大一部分中使用check
函数,请不要尝试这样做代码:你的目标必须让主程序顺利运行,而不是一组漂亮的测试......
答案 1 :(得分:1)
经典TDD概念需要一些额外的修改才能将它们应用于动态语言,如Javascript(由于缺少类,特定的闭包使用......)这就是我们拥有像Jasminejs这样的测试库的方式。 我不能明确告诉你如何处理你的功能,但我知道一切都不需要测试。有些事情真的很明显,他们只需要一些理智检查。经验法则是测试可能破坏的东西。例如验证,数据库访问,用户输入......
答案 2 :(得分:1)
我认为你是在正确的道路上,TDD使代码重复变得更加明显(检查参数代码必须在有或没有TDD的情况下删除它的重复)并且你听取你的测试并分开检查的责任,现在你有两个责任:
在单元测试级别,这是完美的,我认为,或许在其他方面,您需要进行一些集成或系统测试,以检查您是否正确地使用他的检查器编写功能。
答案 3 :(得分:0)
如果有单独的声明,则需要进行测试。因此,在您的情况下,您需要保留要求foo()
和bar()
都使用check
函数的测试。这些测试可能比您编写的原始测试更简单:例如,他们可能只检查是否抛出了错误,而没有查看错误消息。
如果检查功能现在被打破,例如什么也不做,那么会有多个检测器检测到这一点。这不是问题,因为您会将check
函数的测试置于顶部,因此第一次失败将直接指向根本原因。