ios - 在单元测试中使用不可用的初始值设定项模拟 Cocoa 对象

标签 ios swift unit-testing mocking core-bluetooth

我正在使用 Swift 构建一个 iOS 应用程序,它使用苹果的 CoreBluetooth 框架通过低功耗蓝牙与外围设备通信。在对实现 CBCentralManagerDelegateCBPeripheralDelegate 协议(protocol)的自定义 Controller 进行单元测试时,我提供了一个从 CBCentralManager 子类化的测试替身 来模拟CoreBluetooth API 的行为。在适当的时候调用 Controller 的委托(delegate)回调。

到目前为止,这一直运作良好。但是当涉及到调用 CBPeripheralDelegate 回调时,需要传入一个 CBPeripheral。通常,我会伪造提供我自己的子类的组件或模拟 的实例em>CBPeripheral.

问题所在:底层 Objective-C 库中 CBPeripheral 的指定初始化程序被标记为不可用,这阻止了我实例化 CBPeripheral 在我伪造的 CBCentralManager 中,并将其作为参数传递给正在测试的 CBPeripheralDelegate。 (XCode 给我留下了一个编译器错误。)

到目前为止,我已经尝试在我的假子类中提供一个自定义初始化器(这不起作用,因为我最终必须调用不可用的指定初始化),用扩展覆盖初始化器(这显然是不允许的)并调用选择器 (init) 与 Objective-C 运行时,就像我不在乎它不可用一样。最后一种方法似乎是最有前途的,但实际上并没有起作用,并且给我留下了错误类型的非托管对象(我的测试类)。

我肯定在这里遇到了障碍,如果有任何意见,我将非常高兴

  1. 在 init() 不可用的情况下实例化一个CBPeripheral

  2. CBPeripheralDelegate

  3. 单元测试的不同方法

最佳答案

我通过追求 objc-runtime 的想法并在 Objective-C 中创建一个对象工厂,通过其指针调用初始化程序的实现以忽略不可用标记,设法自己解决了这个问题。

更多信息见: http://ijoshsmith.com/2014/06/05/instantiating-classes-by-name-in-swift/ (这在当前的 Swift 中不再有效,但可以很容易地适应)

关于ios - 在单元测试中使用不可用的初始值设定项模拟 Cocoa 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35898171/

相关文章:

unit-testing - 如何卡住考试时间?

iphone - 将 UIImage 转换为 PDF 时应用程序崩溃

ios - 快速:UIPageViewController 操作

ios - MSMessagesAppViewController 没有正确调用 didSelect() ?

ios - CocoaPods 找不到 pod "Alamofire 5.0.0-rc.2 "的兼容版本

c# - 组织执行测试的方法 - C#

ios - 将一维数组转换为具有指定列数的二维数组

objective-c - 计算 XCode 中 URL 处的文件数

ios - 如何使视频预览适合 ImageView Xcode Swift 3

angular - Electron Angular : Running Karma errors because of undefined ipcRenderer inside angular component