JavaScript —单元测试子任务

时间:2018-10-16 15:07:42

标签: javascript unit-testing abstraction black-box

他们说:

  

“您应该测试接口,而不是实现。”

换句话说,您应该关注最终结果,而不是最终结果的实现方式(黑盒测试)。

也有人说,您不应该测试私有功能,而只能测试公开的公共接口。但是我的问题是...

您如何处理依赖于几个私有子任务的公开接口(例如函数)?您应该如何进行测试?

请考虑以下功能calculateDiscountedPrice让我们假装第一个功能是公开可用的(请考虑默认为导出),而其他三个功能是私有的。

// PUBLIC TOP-LEVEL FUNCTION
export default function calculateDiscountedPrice(price, discount) {
    const dollarsOff = getDollarsOff(price, discount);
    return round(price - dollarsOff);
}

// PRIVATE SUBTASK
function getDollarsOff(price, discount) {
    return price * discount;
}

// PRIVATE SUBTASK
function round(number, precision = 2) {
    return isInt(number) 
    ? number
    : number.toFixed(precision);
}

// PRIVATE SUBTASK
function isInt(number) {
    return number % 1 === 0;
}

用法示例:

console.log(calculateDiscountedPrice(100, 0.75)) // 25

如您所见,calculateDiscountedPrice是我们要公开的公共函数,因此我们应该对其进行单元测试。但是其他三个子任务呢?我们为什么不应该测试那些?涵盖calculateDiscountedPrice的测试是否也涵盖其他三个?

1 个答案:

答案 0 :(得分:2)

很正确,您不应该单独测试私有功能。

编写针对公开代码的测试时,应考虑代码中尽可能多的分支-因此,测试也将涉及所有私有函数。

进一步严格地说,您不需要为所有公共可用功能编写测试,否则您也将测试实现。

因此对于此特定示例,您可以编写如下测试:

  • price传递给10之类的整数,以得出调用isInt的“负”结果(准确地说,数字结果为0)
  • price传递给不像7.35这样的整数,以得出调用isInt的“正”结果
  • 通过零discount
  • 传递非零的discount
  • 使用以前的变体等的组合。

让我注意到,如果从一开始就使用TDD技术,那么这些变更本质上就是这些测试用例。

让我也建议您花几分钟时间阅读一下article的Bob叔叔,他是软件工程领域的专业人士。