Как один модуль тестирует код, взаимодействующий с Core API Bluetooth?

Я хотел бы провести модульное тестирование класса, который действует как 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 а также init методы CBPeripheralManager а затем просто создать экземпляр в PeripheralManagerWrapperинициализатор.

1 ответ

Решение

ИМХО, основные API-интерфейсы Bluetooth идеально подходят для модульного тестирования. Все обратные вызовы делегата принимают менеджер и соответствующие параметры, поэтому, если вы будете следовать шаблону, в котором вы используете эти аргументы вместо внутреннего состояния, вы сможете передать все, что захотите. Использование фиктивных объектов - лучший способ сделать это. При юнит-тестировании не стоит пытаться издеваться над поведением менеджеров. Вы должны сосредоточиться на проверке взаимодействия вашего кода с API и ничего более.

Упаковщики могут лучше подходить для тестирования интеграции. Но на самом деле, интеграционное тестирование кода Core Bluetooth лучше проводить вручную, насколько я понимаю. Стек не достаточно стабилен, чтобы обеспечить надежное тестирование, и тестовый код также должен быть защищен от ошибок стека, что на самом деле очень сложно, поскольку, очевидно, они не документированы и не предсказуемы, просто глядя на API. С другой стороны, ваш тестовый код должен был бы имитировать и ошибочное поведение стека. Возможны случаи, когда это возможно, но тестовый код будет таким же сложным, если не больше, чем код, который вы тестируете.

Другие вопросы по тегам