我正在努力将目光投向单元测试的实践。我已经读过,单元测试不应该依赖于实现。
据我所知,例如,如果我们有一个函数int addTwoNumbers (int a, int b)
,我们应该测试例如加法是否返回正确的结果(即addTwoNumbers (2, 2) == 4)
),而我们不在乎,例如,addTwoNumbers
仅调用一次operator +
-为此,不妨使用位操作。
对我来说,这似乎很合理,并且-在我看来-在测试和代码之间提供了不错的分离。
输入模拟框架。从阅读他们的文档可以看出,它们的功能相当于
(a)生成实现基类(存根)和某些接口的占位符功能的对象
(b)检查是否根据测试人员提出的期望调用了该功能。
我对(a)没问题-我了解我们有时需要对外部依赖项的某些功能进行硬编码以进行测试。我不明白,为什么我们要检查被测试的代码是否以测试人员期望的方式调用了模拟功能。
我们不应该只对所测试的方法返回什么或它如何修改其out参数而不真正关心其实现细节感兴趣吗?模拟框架的验证功能是否不会在测试代码和测试代码之间引入紧密的联系?
答案 0 :(得分:1)
不过我不明白,为什么我们要检查被测试的代码是否以测试人员期望的方式调用了模拟功能?
因为方法的约定并不总是返回某些东西或修改其参数。有时,该方法的合同具有(或包括)副作用。考虑以下方法的示例:
void notifyServerOfError(error: string) {
this.http.post('/api/errors', {
error: error,
ip: myIpAddress
});
}
此方法不返回任何内容。它不会修改其参数。它的唯一责任是将包含特定详细信息的特定对象发送到特定URL。因此,对该方法进行单元测试应该验证合同是否得到遵守。
一种好的方法是模拟http
依赖性,并检查在调用此方法时,其post()
方法是否确实以正确的URL和正确的数据被调用。 / p>