【问题标题】:Can test be green from the very beginning in TDD?测试可以从一开始就在 TDD 中是绿色的吗?
【发布时间】:2014-02-03 17:31:25
【问题描述】:

假设我有函数foo()

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

我对其进行了以下测试:

  1. foo() 存在;
  2. foo() 从字符串中剥离 a's 并且没有 a's 对字符串不做任何事情;
  3. 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、undefined、number、array、boolean、regexp等对象不提供replace()方法。

我认为我需要这个测试,只是因为 JS 团队可能会针对这种特殊情况将 TypeError 更改为 MissingMethodError 之类的东西,但我会违反 Red > Green > Refactor 原则。我应该如何解决这种情况?

【问题讨论】:

  • if(string && !string.replace){ throw "no replace on arg"; }
  • @dandavis,这不是关于“如何实施此检查”,而是“如果在实施检查之前检查是否为绿色,该怎么办”。
  • 除此之外,传入5(比如说)会过去。

标签: javascript unit-testing testing tdd methodology


【解决方案1】:

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

1) foo 存在;

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

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

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

3) foo 去掉 a's。

红色,因为它没有。现在实施;现在您的所有测试都通过了,并且所有测试都以红色开始。

这似乎是一种人为的方法,当然是,而且事先知道如何编写测试以遵守红绿重构并不容易。但是你做的越多,它就越容易。

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

【讨论】:

  • 好吧,在我的特殊情况下,我应该只包括绿色测试,以后避免这种情况,还是不应该?
  • 在您的情况下,我将添加绿色测试,暂时更改被测系统以证明如果停止抛出所需的异常,测试将捕获,然后恢复到正确的状态。
【解决方案2】:

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

最终,您应该问自己是否值得拥有自定义错误类型。在使用您的功能时更容易测试和操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多