2012-04-03 6 views
1

Ich habe ein Unit-Test-Modul von SenTestCase abgeleitet. Ich hätte gerne eine Komponententestmethode, die ein UIDocument abgeleitetes Dokument laden würde, das ich zuvor in der Anwendungs-Sandbox gespeichert habe. Beachten Sie, dass bei diesem Test das Dokument lokal geladen wird (iCloud ist nicht konfiguriert). Ich weiß, openWithCompletionHandler läuft asynchron, so verstehe ich, würde dies nie funktionieren, sobald die Testfunktion vom Stapel ausgeführt wird. Im Folgenden Code gegeben ist meine Absicht, um anzuzeigen, (natürlich funktioniert es nicht):Wie teste ich Unit-Test 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."); 
     } 
    }]; 
} 

Meine Frage ist wirklich ist es eine Möglichkeit, openWithCompletionHandler aus Unit Testing Framework zu testen? Es macht mir nichts aus, wenn ich den gesamten Dokumentladevorgang synchron innerhalb eines Codeblocks ausführen muss. Da dies ein Testcode ist, dachte ich, dass dies im Gegensatz zu Code akzeptabel wäre, der asynchron auf dem Gerät ausgeführt werden muss.

Vielen Dank im Voraus.

+0

Ich denke jetzt, es gibt einen besseren Weg, dies zu erreichen. Mir ist klar geworden, was ich wirklich will, ist, instentsForType und loadFromContents zu testen. Also werde ich in meiner Testsuite eine von MyDocument abgeleitete Scheinklasse erstellen, die saveToUrl und openWithCompletionHandler implementiert, die die Aufrufe contentsForType und loadFromContents einfach synchron zu MyDocument umleiten. Es gibt keinen Sinn, sich mit asynchronen Datei-E/A-Dingen zu befassen, wenn Sie die Datenverarbeitung in diesen Methoden testen wollen. Wenn das mein Problem behebt, werde ich diese Frage aktualisieren. –

+1

Ich erstellte eine ableitende UIDocument abgeleitete Klasse und eine NSMutableData abgeleitete Klasse, in der ich meine Datenklasse eingewickelt NSCoding-Protokoll implementieren. Ich habe ein paar Delegationen gemacht. Aber es hat nicht funktioniert. Ich muss mit meinem Projekt weitermachen, also gebe ich das Unit-Testing-UIDocument auf. Wenn Sie auf bessere Strategien hinweisen können, tun Sie dies bitte. Ich bin immer noch interessiert zu wissen. –

Antwort

0

Dieses Problem dauerte eine Weile, um herauszufinden. Ich liebe Komponententests, aber wenn Sie SenTestCase verwenden, werden Ihre Tests nicht in der gleichen Umgebung ausgeführt, in der Ihr normaler Code läuft. Am wichtigsten ist, dass Ihnen eine Hauptschleife fehlt, in der eine Ausführungsschleife enthalten ist, sodass alles mit asynchronen Rückrufen dazu neigt, nichts zu tun.

Also, was ist die Lösung? Stellen Sie selbst eine Laufschleife bereit und lassen Sie sie laufen, bis der Block aufgerufen wird. Wir verwenden eine __block Variable, die wir im Completion-Block setzen, um zu sehen, wann wir aufhören können, die Run-Schleife zu laufen.

-(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

Sorry über die späte Antwort und vielen Dank @redlightbulb –