Я написал библиотеку, реализующую «Обещание». Оказалось, что эта концепция полезна не только для решения сложных асинхронных задач, но и для тестирования:
Предположим, у вас есть какой-то асинхронный метод и вы хотите проверить, будет ли вызван обработчик завершения и вернет ли он ожидаемый результат. В качестве бонуса вы также хотите установить тайм-аут, в течение которого тестер ожидает обработчик завершения. Если он истекает, тест должен провалиться.
Общий блок обработчика завершения:
typedef void (^completion_block_t)(id result);
Ваш тест, асинхронный метод, который может основываться на цикле выполнения:
- (void) asyncFooWithCompletion:(completion_block_t)completionHandler;
Ваш тест может выглядеть следующим образом:
- (void) testAsyncFooWithCompletion
{
// Your test - executing on the main thread.
RXPromise* handlerPromise = [RXPromise new];
[foo asyncFooWithCompletion:^(id result){
// possibly perform assertions
...
if (result is expected) {
// expected in this test scenario
// resolve promise with a value indicating success:
[handlerPromise fulfillWithValue:@"OK"];
}
else {
// unexpected in this test scenario
// resolve promise with an error:
[handlerPromise rejectWithReason:@"Unexpected result"];
}
}];
Примечание. Рабочая нагрузка asyncFooWithCompletion:
s может быть запланирована в цикле выполнения, который выполняется в соответствующем потоке, например основной поток.
Обработчик завершения может также выполняться в том же цикле выполнения, например на основной ветке.
// Set a timeout. If the timeout expires before the handler get called,
// the promise will be resolved with a "timeout error":
[handlerPromise setTimeout:5.0];
// Register handlers, which get called when _handlerPromise_ will be resolved.
// We did perform a all assertions in the completion handler. Thus here,
// just catch unexpected failures - including a timeout:
[handlerPromise.thenOn(dispatch_get_main_queue(), nil,
^id(NSError* error) {
// We are on the main thread
ADD_FAILURE() << [[error description] UTF8String];
return error;
})
runLoopWait]; // wait on the current run loop.
// if we reach here, assertions have been executed (on the main thread)
// and all handlers have been returned.
} // end test
person
CouchDeveloper
schedule
07.09.2013