Это связано с моим предыдущим вопросом , но достаточно разным, и я решил, что добавлю его в новый. У меня есть некоторый код, который выполняет асинхронный вызов в пользовательской очереди, а затем выполняет блок завершения в главном потоке после завершения. Я хотел бы написать модульный тест вокруг этого метода. Мой метод на MyObject
выглядит следующим образом.
+ (void)doSomethingAsyncThenRunCompletionBlockOnMainQueue:(void (^)())completionBlock {
dispatch_queue_t customQueue = dispatch_queue_create("com.myObject.myCustomQueue", 0);
dispatch_async(customQueue, ^(void) {
dispatch_queue_t currentQueue = dispatch_get_current_queue();
dispatch_queue_t mainQueue = dispatch_get_main_queue();
if (currentQueue == mainQueue) {
NSLog(@"already on main thread");
completionBlock();
} else {
dispatch_async(mainQueue, ^(void) {
NSLog(@"NOT already on main thread");
completionBlock();
});
}
});
}
Я добавил тест основной очереди для дополнительной безопасности, но он всегда попадает в dispatch_async
. Мой модульный тест выглядит следующим образом.
- (void)testDoSomething {
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
void (^completionBlock)(void) = ^(void){
NSLog(@"Completion Block!");
dispatch_semaphore_signal(sema);
};
[MyObject doSomethingAsyncThenRunCompletionBlockOnMainQueue:completionBlock];
// Wait for async code to finish
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);
STFail(@"I know this will fail, thanks");
}
Я создаю семафор, чтобы заблокировать завершение теста до выполнения асинхронного кода. Это будет прекрасно работать, если мне не потребуется запускать блок завершения в главном потоке. Однако, как отметили несколько человек в ответе на вопрос, который я упомянул выше, тот факт, что тест выполняется в главном потоке, а затем я ставлю в очередь блок завершения в главном потоке, означает, что я просто зависну навсегда.
Вызов основной очереди из асинхронной очереди - это шаблон, который я часто вижу для обновления пользовательского интерфейса и тому подобное. У кого-нибудь есть лучший шаблон для тестирования асинхронного кода, который обращается к основной очереди?