我正在使用 Swift 构建一个 iOS 应用程序,它使用苹果的 CoreBluetooth 框架通过低功耗蓝牙与外围设备通信。在对实现 CBCentralManagerDelegate 和 CBPeripheralDelegate 协议(protocol)的自定义 Controller 进行单元测试时,我提供了一个从 CBCentralManager 子类化的测试替身 来模拟CoreBluetooth API 的行为。在适当的时候调用 Controller 的委托(delegate)回调。
到目前为止,这一直运作良好。但是当涉及到调用 CBPeripheralDelegate 回调时,需要传入一个 CBPeripheral。通常,我会伪造提供我自己的子类的组件或模拟 的实例em>CBPeripheral.
问题所在:底层 Objective-C 库中 CBPeripheral 的指定初始化程序被标记为不可用,这阻止了我实例化 CBPeripheral 在我伪造的 CBCentralManager 中,并将其作为参数传递给正在测试的 CBPeripheralDelegate。 (XCode 给我留下了一个编译器错误。)
到目前为止,我已经尝试在我的假子类中提供一个自定义初始化器(这不起作用,因为我最终必须调用不可用的指定初始化),用扩展覆盖初始化器(这显然是不允许的)并调用选择器 (init) 与 Objective-C 运行时,就像我不在乎它不可用一样。最后一种方法似乎是最有前途的,但实际上并没有起作用,并且给我留下了错误类型的非托管对象(我的测试类)。
我肯定在这里遇到了障碍,如果有任何意见,我将非常高兴
在 init() 不可用的情况下实例化一个CBPeripheral
CBPeripheralDelegate
单元测试的不同方法
最佳答案
我通过追求 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/