XCTestで非同期ブロックのテストを書く

  • 40
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

XCTestで、こんな感じで非同期処理のテストを書いた場合、

[SNSUser loginWithBlock^(SNSUser* user, NSError* error) {
    XCTAssertNotNil(user, @"hoge");
    XCTAssertNil(error, @"fuga");
}];

一見テストが通ったと見せかけて、実はBlocksの中が
実行される前にテストが終わっていたりします。
(Blocks内はテストしてないけどTest Succeededってなる)
地味に最初はひっかかる人もいるんではないでしょうか。

XCTestでは非同期処理のテストができないと思っている人を時々見かけますが、
Blocksの中に書いた処理が走るまで待機させることで一応テストできます。

// テスト実行完了フラグ
__block BOOL isFinished = NO;

[SNSUser loginWithBlock^(SNSUser* user, NSError* error) {
    XCTAssertNotNil(user, @"hoge");
    XCTAssertNil(error, @"fuga");
    // Blocksの中のテストが終わったら完了フラグをYESに
    isFinished = YES;
}];
// 完了フラグがYESになるまで待機
while (!isFinished) {
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}
XCTAssertTrue(isFinished, @"");

上記例のテストコードだと最大で1秒まで待機するようにしていますが、
念のためisFinishedの値を確認しておくと安心かなと思います。