How is one unit test code that interacts with the basic Bluetooth APIs?

I would like a unit test class that acts like CBPeripheralManagerDelegate in the CBPeripheralManager class. As a rule, in order to drown out the external dependency of a class, I would use either a dependency injection form, passing through the class initializer, or through a property. When working with the single-user APIs, I can use libraries like Kiwi to drown out the class level method that returns singleton (ie [ClassName stub:@selector(sharedInstance) andReturn:myStubbedInstance] ). The problem with the CBPeripheralManager ridicule is that its initializer accepts a delegate instance. Therefore, any code that uses my class would have to do something like this:

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

Then, to unit test my PeripheralManagerWrapper class, I could just instantiate it and pass it to the mocked CBPeripheralManager . However, I don't like it if any calling code of my wrapper object had to go through this setting. Is there a better solution to this situation? I used both Kiwi and OCMockito, but none of them can provide this functionality, perhaps the attenuation of the alloc and init CBPeripheralManager , and then just an instance of the instance in the PeripheralManagerWrapper initializer.

+4
source share
1 answer

IMHO, the basic Bluetooth interfaces are ideal for unit testing. All delegate callbacks are accepted by the manager and the corresponding parameters, so if you follow the template in which you use these arguments, instead of the internal state, you can pass whatever you want. Using mock objects is the best way to do this. During unit testing, you should not try to scoff at the behavior of managers. You should focus on checking how your code interacts with the API and nothing more.

Packers can respond better to integration tests. But in fact, integration testing of Core Bluetooth code is best done manually for my experience. The stack is not stable enough to provide reliable testing, and the test code should also be strengthened against stack errors, which is really difficult, because, obviously, they are not documented or unpredictable, just looking at the API. Although, on the other hand, your test code will also have to model the erroneous behavior of the stack. There may be times when this is possible, but the test code will be just as complex, if not more so than the one you are testing.

+4
source

All Articles