首页 > 解决方案 > 在 Swift 中对私有变量进行单元测试

问题描述

我很难掌握如何在我的所有字段都是私有的类中实现单元测试。

该课程正在使用 BLE 和 CoreLocation 计算用户的位置 - 不是那么重要。我有一个协议,当找到一个新位置时,我会调用它,所有符合该协议的类都将收到一个房间 ID 和房间名称。那么,这意味着我班级中的所有字段实际上都是私有的,因为是的,没有理由任何外部班级都应该访问它们吗?但这也意味着我无法在该类中测试任何内容,即使有很多我想测试的功能。我的意思是,我可以将变量设置为内部变量而不是私有变量,但是仅仅为了单元测试而这样做似乎是错误的。我听说过依赖注入,但这似乎需要付出很多努力。

例如我有这个功能:


private var beacons: [AppBeacon] = []
private var serverBeacons:[Beacon] = []

private func addBeacons(serverBeacons: [Beacon]){
        for beacon in serverBeacons {
            let beacon = AppBeacon(id: beacon.id, uuid: beacon.uuid, building: beacon.building, name: beacon.name)
            beacons.append(beacon)
       }
   }

例如,我无法测试信标阵列是否真的按照我的意愿填满。我的类的公共特性基本上是一个名为 startLocating 的函数,结果是房间 ID 和名称,我知道在黑盒测试中模仿了哪些单元测试(对吗?)我不应该关心中间步骤,但老实说,我应该说这么多功能,没关系吗?并假设我确实用我选择的一些 rssi 值填充了信标,实际的位置算法在 node.js 服务器上执行,所以老实说我不知道​​要测试客户端什么?

这是经典的 MVC,在截止日期之前我无法更改它的架构,所以我不知道从这里开始的最佳方式是什么?只是不测试功能?使字段内部而不是私有?我们在服务器端对算法本身进行测试,因此测试房间 id 是否是预期的房间 id,已经测试过了。

我在另一篇文章中读到以下内容:

“根据定义,单元测试是黑盒测试,这意味着您不关心您测试的单元的内部结构。您主要感兴趣的是根据您在单元测试中提供的输入来查看单元输出是什么。现在,通过输出,我们可以断言几件事:

在所有情况下,我们只对公共接口感兴趣,因为它是与世界其他地方通信的接口。私人物品不需要仅仅因为任何私人物品都被公共物品间接使用而进行单元测试。诀窍是编写足够的测试来锻炼公共成员,以便完全覆盖私有成员。

此外,要记住的一件重要事情是单元测试应该验证单元规范,而不是它的实现。验证实现细节增加了单元测试代码和被测代码之间的紧密耦合,这有一个很大的缺点:如果被测实现细节发生变化,那么单元测试很可能也需要改变,这降低了拥有的好处对那段代码进行单元测试。”

从那我基本上理解为我不应该对此进行单元测试?

标签: iosswiftunit-testingprivate

解决方案


如果您有一个private var可以帮助您编写单元测试的工具,请将其更改为private(set) var可以读取(但不能更改)。

暴露内脏可能会打扰您。如果是这样,则可能有另一种类型等待从视图控制器中提取。


推荐阅读