【问题标题】:Mocking and unit testing implementation dependencies模拟和单元测试实现依赖
【发布时间】:2018-07-21 12:11:31
【问题描述】:

我正试图围绕单元测试的实践展开思考。我读过单元测试不应该依赖于实现。

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

这对我来说似乎是合理的,并且 - 在我看来 - 在测试和代码之间提供了一个不错的解耦。

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

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

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

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

难道我们不应该只关心被测试的方法返回什么或者它如何修改它的输出参数而不真正关心它的实现细节吗?模拟框架的验证功能是否不会在测试代码和测试代码之间引入紧密耦合?

【问题讨论】:

    标签: unit-testing mocking


    【解决方案1】:

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

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

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

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

    这样做的一个好方法是模拟 http 依赖项,并检查在调用此方法时,它的 post() 方法确实是使用正确的 URL 和正确的数据调用的。

    【讨论】:

      猜你喜欢
      • 2016-02-19
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 2017-09-25
      • 2016-02-19
      • 1970-01-01
      • 1970-01-01
      • 2021-02-28
      相关资源
      最近更新 更多