2012-04-03 118 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。因此,在我的測試套件中,我將創建一個從MyDocument派生的模擬類,它將實現saveToUrl和openWithCompletionHandler,它們將同時將contentsForType和loadFromContents調用重定向到MyDocument。如果您的目的是測試這些方法中的數據處理,那麼處理異步文件I/O內容就沒有意義了。如果這能解決我的問題,那麼我會來更新這個問題。 – 2012-04-04 08:11:06

+1

我創建了一個內存映射的UIDocument派生類和一個NSMutableData派生類,其中包裝了實現NSCoding協議的數據類。我製作了幾個代表團。但它沒有奏效。我必須繼續我的項目,所以我放棄了單元測試UIDocument。如果你能指出更好的策略,請這樣做。我仍然有興趣知道。 – 2012-04-05 10:26:30

回答

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 – 2013-03-13 02:46:32