TDD 测试从一开始就可以是绿色的吗?

问题描述 投票:0回答:3

想象我有功能

foo()

var foo = function(string) {
    return string.replace(/a/g, '');
};

我对其进行了以下测试:

  1. foo()
    存在;
  2. foo()
    从字符串中剥离
    a
    ,并且对没有
    a
    的字符串不执行任何操作;
  3. 如果给定字符串以外的东西,
  4. foo()
    会抛出
    TypeError

问题出在测试#3上——然而它从一开始就是绿色的,这不是我的优点。我希望写出这样的东西:

var foo = function(string) {
    if (typeof string !== 'string') {
        throw new TypeError('argument should be a string');
    }

    return string.replace(/a/g, '');
};

但我不能,因为没有测试。所以

foo()
确实会抛出 TypeError,但不是因为参数类型错误,而是因为作为参数给出的 null、未定义、数字、数组、布尔值、正则表达式等对象不提供
replace()
方法。

我认为我需要这个测试,只是因为 JS 团队可能会将这种特殊情况下的

TypeError
更改为
MissingMethodError
之类的东西,但我会违反红>绿>重构原则。我该如何解决这种情况?

javascript unit-testing testing tdd methodology
3个回答
6
投票

这种情况可能会发生,但最好避免。在这种情况下,您可以通过以不同的顺序编写测试来避免这种情况。

1) foo 存在;

红色是因为 foo 当然不存在。写一个空的 foo();现在它是绿色的。

2) 如果参数不是字符串,则 foo 会抛出 TypeError。

红色是因为 foo 从不抛出 TypeError (或其他任何错误)。让 foo 无条件抛出 TypeError;现在所有测试都是绿色的。

3) foo 去掉 a。

红色,因为没有。现在实施;现在你所有的测试都通过了,所有的测试都开始是红色的。

这似乎是一种人为的方法,当然确实如此,并且提前知道如何编写测试以遵守红绿重构并不容易。但你做得越多,它就会变得越容易。

红绿重构确实很重要,值得尝试遵循,因为如果测试一开始是绿色的,那么它可能不会对被测系统进行任何有意义的测试。有时,就像这个例子一样,你会遇到它;您可以调整被测系统以强制显示红色,但也可以尝试从中学习(正如您通过提出这个问题所做的那样),以便下次会更好。


0
投票

您可以测试您的 TypeError 是否具有正确的消息。目前,这可能不是您所期望的。

最终,您应该问自己是否值得拥有自定义错误类型。使用函数时更容易测试并更容易采取行动。


0
投票

这是旧的,但我的 5 美分:你不应该测试函数的存在。您应该测试需求。并且函数的存在无疑是一个要求。

© www.soinside.com 2019 - 2024. All rights reserved.