模拟和单元测试实现依赖关系



我正试图了解单元测试的实践。我读过单元测试不应该依赖于实现。

我理解这一点的方式是,例如,如果我们有一个函数int addTwoNumbers (int a, int b),我们应该测试,例如加法是否返回正确的结果(即addTwoNumbers (2, 2) == 4)(,而不应该关心,例如,addTwoNumbers是否只调用operator +一次——它还不如对此使用位操作。

对我来说,这似乎是合理的,而且在我看来,它提供了测试和代码之间的良好解耦。

进入模拟框架。从阅读他们的文档中我可以看出,他们的功能相当于

(a( 生成实现基类(存根(和的某些接口的占位符功能的对象

(b( 检查是否根据测试人员提出的期望调用了该功能。

我对(a(没有问题——我知道我们有时需要硬编码一些外部依赖项的功能来进行测试。但我不明白,为什么我们要检查测试代码是否以测试人员期望的方式调用了mock的功能。

难道我们不应该只对测试方法返回的内容或它如何修改out参数感兴趣,而不关心它的实现细节吗?mocking框架的验证功能是否没有在测试代码和测试代码之间引入紧密耦合?

我不明白,为什么我们要检查测试代码是否以测试人员期望的方式调用mock的功能

因为方法的约定并不总是返回某些内容或修改其参数。有时合同的方法是(或包括(有副作用。以以下方法为例:

void notifyServerOfError(error: string) {
this.http.post('/api/errors', {
error: error,
ip: myIpAddress
});
}

此方法不返回任何内容。它不会修改其参数。它的唯一责任是将包含特定详细信息的特定对象发送到特定URL。因此,单元测试这种方法应该验证合同是否得到遵守。

一个很好的方法是模拟http依赖关系,并检查在调用此方法时,其post()方法是否确实使用正确的URL和正确的数据进行了调用。

最新更新