JavaScript — 单元测试子任务
JavaScript — Unit Testing Subtasks
他们说:
"You should test the interface, not the implementation."
换句话说,您应该关心最终结果,而不是它是如何完成的(黑盒测试)。
也有人说你应该不测试私有函数,而只是暴露的public接口。但我的问题是...
对于依赖于多个私有子任务的 public 仅公开的接口(例如,函数),您如何处理?你应该如何去测试它?
考虑以下函数 calculateDiscountedPrice
。 让我们假设第一个函数 public 仅可用(认为导出默认值)而其他 3 个函数是私有的。
// 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
是我们公开的 public 函数,因此我们应该对其进行单元测试。但是其他三个子任务呢?为什么我们不应该测试那些?涵盖 calculateDiscountedPrice
的测试是否也涵盖其他三个?
你说得对,你不应该单独测试私有函数。
当您为公开可用的代码编写测试时,您应该考虑尽可能多地在代码中进行分支 - 这样您的测试也会触及所有私有函数。
更严格地说,你不需要为所有公开可用的功能编写测试,否则你也会测试实现。
因此,对于这个特定示例,您可以编写如下测试:
- 将
price
传递给像 10
这样的整数,以通过调用 isInt
的 "negative" 结果(准确地说 - 会有一个数字结果0)
- 将
price
传递给一个非整数,如 7.35
以通过调用 isInt
的 "positive" 结果
- 过零
discount
- 传递非零值
discount
- 使用先前变体等的组合
请注意,如果您从一开始就使用 TDD
技术,那么您基本上会得到这些测试用例。
我也建议你花几分钟时间读一读 Uncle Bob 的这篇 article,他是软件工程方面的专业人士。
他们说:
"You should test the interface, not the implementation."
换句话说,您应该关心最终结果,而不是它是如何完成的(黑盒测试)。
也有人说你应该不测试私有函数,而只是暴露的public接口。但我的问题是...
对于依赖于多个私有子任务的 public 仅公开的接口(例如,函数),您如何处理?你应该如何去测试它?
考虑以下函数 calculateDiscountedPrice
。 让我们假设第一个函数 public 仅可用(认为导出默认值)而其他 3 个函数是私有的。
// 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
是我们公开的 public 函数,因此我们应该对其进行单元测试。但是其他三个子任务呢?为什么我们不应该测试那些?涵盖 calculateDiscountedPrice
的测试是否也涵盖其他三个?
你说得对,你不应该单独测试私有函数。
当您为公开可用的代码编写测试时,您应该考虑尽可能多地在代码中进行分支 - 这样您的测试也会触及所有私有函数。
更严格地说,你不需要为所有公开可用的功能编写测试,否则你也会测试实现。
因此,对于这个特定示例,您可以编写如下测试:
- 将
price
传递给像10
这样的整数,以通过调用isInt
的 "negative" 结果(准确地说 - 会有一个数字结果0) - 将
price
传递给一个非整数,如7.35
以通过调用isInt
的 "positive" 结果
- 过零
discount
- 传递非零值
discount
- 使用先前变体等的组合
请注意,如果您从一开始就使用 TDD
技术,那么您基本上会得到这些测试用例。
我也建议你花几分钟时间读一读 Uncle Bob 的这篇 article,他是软件工程方面的专业人士。