一个单元如何测试与Core Bluetooth API交互的代码?

时间:2014-01-24 15:41:00

标签: objective-c unit-testing core-bluetooth kiwi ocmockito

我想对CBPeripheralManagerDelegate类充当CBPeripheralManager的类进行单元测试。通常,为了存根外部类依赖项,我将通过类初始化程序或通过属性传入一种依赖注入形式。在处理基于单例的API时,我已经能够使用像Kiwi这样的库来存根返回单例的类级方法(即[ClassName stub:@selector(sharedInstance) andReturn:myStubbedInstance])。模拟CBPeripheralManager的问题是它的初始化程序接受委托实例。因此,使用我的类的任何代码都需要执行以下操作:

PeripheralManagerWrapper *wrapper = [[PeripheralManagerWrapper alloc] init];
CBPeripheralManager *peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:wrapper queue:nil options:nil];
wrapper.peripheralManager = peripheralManager;

然后,为了对我的PeripheralManagerWrapper类进行单元测试,我可以简单地实例化它并传入一个模拟的CBPeripheralManager。但是,我不喜欢要求我的包装器对象的任何调用代码必须通过此设置。处理这种情况有更好的模式吗?我已经使用了Kiwi和OCMockito,但似乎都没有提供这个功能,可能是对alloc的{​​{1}}和init方法进行存根,然后只是在{{1}中实例化实例}} 的初始化程序。

1 个答案:

答案 0 :(得分:4)

恕我直言,核心蓝牙API非常适合单元测试。所有委托回调都采用管理器和相关参数,因此如果您遵循使用这些参数而不是内部状态的模式,那么您将能够传递任何您想要的内容。使用模拟对象是执行此操作的最佳方法。在进行单元测试时,您不应该试图模仿经理的行为。您应该专注于验证代码与API的交互,仅此而已。

Wrappers可能更适合集成测试。但实际上,核心蓝牙代码的集成测试最好根据我的经验手动完成。堆栈不够稳定,无法进行可靠的测试,而且测试代码也必须加强堆栈错误,这实际上很难,因为很明显,仅通过查看API就没有记录或预测。另一方面,您的测试代码也必须模拟堆栈的错误行为。可能存在可能的情况,但测试代码与您正在测试的代码一样复杂。