2012-04-03 3 views
1

SenTestCaseから派生したユニットテストモジュールがあります。以前にアプリケーションサンドボックスに保存したUIDocumentの派生ドキュメントをロードするユニットテストメソッドが必要です。このテストはドキュメントをローカルに読み込むことに関するテストです(iCloudは設定されていません)。私はopenWithCompletionHandlerが非同期に実行されるので、テスト機能がスタックから実行されるとすぐにはこれが動作しないと理解しています。コードは私の意思を示すために与えられているの下には(もちろん、それは動作しません):ユニットテストopenWithCompletionHandlerを行うには

-(void)testLoadingDocument{ 
    ... 
    MyDocument *document = [[MyDocument alloc] initWithFileURL:destUrl]; 
    STAssertNotNil(document, @"Document is nil"); 

    NSLog(@"LOAD: %@", document.fileURL); 
    [document openWithCompletionHandler:^(BOOL success) { 
     NSLog(@"openWithCompletionHandler success = %@", success); 
     if (success) { 
      // document.packet will be filled by loadFromContents 
      STAssertNotNil(document.packet, @"document.packet is nil."); 
     } 
    }]; 
} 

私の質問は本当にユニットテストフレームワーク内からopenWithCompletionHandlerをテストする方法はありますか?コードブロック内でドキュメントの読み込み操作を同期して実行する必要があるかどうかは気にしません。これはテストコードなので、デバイス上で非同期に実行する必要があるコードとは違って、これが受け入れられると思いました。

事前に感謝します。

+0

これを達成するためのよりよい方法があると私は今思っています。 contentsForTypeとloadFromContentsをテストすることが本当に欲しいと分かりました。私のテストスイートでは、saveToUrlとopenWithCompletionHandlerを実装するMyDocumentから派生した模擬クラスを作成し、単にcontentsForTypeとloadFromContentsの呼び出しをMyDocumentに同期的にリダイレクトします。あなたの目的がそれらのメソッドでデータ処理をテストすることであれば、非同期ファイルの入出力を扱う必要はありません。それが私の問題を解決するならば、私はこの質問を更新します。 –

+1

私はメモリマッピングされたUIDocument派生クラスとNSCodingプロトコルを実装するデータクラスをラップしたNSMutableData派生クラスを作成しました。私はいくつかの代表団を作りました。しかし、それは動作しませんでした。私は自分のプロジェクトを進める必要があるので、UIDocumentのユニットテストをあきらめています。あなたがより良い戦略を指摘することができれば、そうしてください。私はまだ知りたいと思っています。 –

答えて

0

この問題は、私には分かりません。私は単体テストが大好きですが、SenTestCaseを使用すると、あなたのテストはあなたの普通のコードと同じ環境では実行されません。最も重要なのは、実行ループがあるメインループが不足しているため、何もしない非同期コールバックのものがあります。

解決策は何ですか?実行ループを自分で提供し、ブロックが呼び出されるまで実行します。我々は実行ブロックの実行を止めることができるかを見るために、完了ブロックに設定した変数__blockを使用します。

-(void)testOfAsyncCallingMethod{ 

    __block bool wasCalled = NO; 

    [testingObject methodThatRunsACompletionBlock:^{ 
     wasCalled = YES; 
    }]; 

    NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:10]; 
    while (wasCalled == NO && [loopUntil timeIntervalSinceNow] > 0) { 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
           beforeDate:loopUntil]; 
    } 
} 
+0

遅れて返事と申し訳ありませんが非常に@redlightbulb –