説明されているパターンを使用しようとしています: Grand Central Dispatch and unit testing、完了時にメイン キューを呼び出すユニット テスト async キューのパターン、主にhttps://github.com/AFNetworking/AFNetworking/issues/466# issuecomment-7917445 .
私の単体テストでは、いくつかのメソッドの非同期フローを「まっすぐにする」必要があります (fx AFNetworking は操作を要求します)。
これは、そのような「強制同期操作」のテスト内で使用するものです。
@property (nonatomic, assign) dispatch_semaphore_t semaphore;
// ...
- (void)runTestWithBlock:(void (^)(void))block {
self.semaphore = dispatch_semaphore_create(0);
block();
while (dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_NOW))
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate dateWithTimeIntervalSinceNow:2]];
dispatch_release(self.semaphore);
}
- (void)blockTestCompletedWithBlock:(void (^)(void))block {
dispatch_semaphore_signal(self.semaphore);
if (block) {
block();
}
}
fx dateWithTimeIntervalSinceNow:10を使用する場合、つまりゼロより大きい値 (引用された SO トピックや Github コメント状態など) を使用すると、テストで同等の余分な有害な遅延が発生します。...SinceNow:0...を設定すると、すべてのテストが遅延なく動作し、この0値に問題は見られません。
アップルのドキュメントは次のように述べています。
Runs the loop once, blocking for input in the specified mode until a given date.
If no input sources or timers are attached to the run loop, this method exits immediately and returns NO; otherwise, it returns after either the first input source is processed *or* limitDate is reached.
この「または」により、コードに悪影響を与えることなく 0 秒を使用できるかどうかを推測できます。
また、 runMode...メソッドのこのバリエーションを使用する代わりの方法、または引用されたリンクで説明されている問題を解決するためのまったく異なる解決策にも感謝します。