2013-10-01 33 views
12

對不起noob問題,但我想測試一個連接,但我無法驗證請求的返回,因爲測試在完成處理程序之前結束一個執行的機會。要ilustrate:如何測試sendAsynchronousRequest:在XCTest上

-(void)testConnection 
{ 

    [[Conector sharedInstance] performAsynchronousRequestWithServerRequest:_srvRequest completionHandler:^(RequestAsynchronousStatus finishStatus, NSData *data) { 
     if (finishStatus == RequestAsynchronousOK){ 
      _data = data; 
      NSLog(@"Data OK"); 
     } 
    }]; 

    XCTAssertNotNil(_data, @"Data was nil"); 

} 

當我嘗試斷言,_data永遠是零,因爲完成處理程序尚未執行。有一種機制可以迫使測試等待,直到我有了來自sendAsynchronousRequest:方法的一些響應。 在此先感謝。

回答

22

這看起來像你需要的東西:

XCAsyncTestCase:異步能夠SenTestCase子類。

基本上,你應該寫你的測試是這樣的:

- (void)testConnection 
{ 
    [[Conector sharedInstance] performAsynchronousRequestWithServerRequest:_srvRequest completionHandler:^(RequestAsynchronousStatus finishStatus, NSData *data) { 
     if (finishStatus == RequestAsynchronousOK) 
     { 
      _data = data; 
      [self notify:XCTAsyncTestCaseStatusSucceeded]; 
      NSLog(@"Data OK"); 
     } 
    }]; 

    [self waitForTimeout:10]; 

    XCTAssertNotNil(_data, @"Data was nil"); 
} 

通知的waitForTimeout:調用和notify:電話。 10秒應該足夠用於測試,但它將取決於請求本身。

你甚至可以得到更具體的,等待一定的地位,就像這樣:

[self waitForStatus: XCTAsyncTestCaseStatusSucceeded timeout:10]; 

這樣,如果連接失敗通知XCTAsyncTestCaseStatusSucceeded狀態,等待通話將超時,您的測試將失敗(正如它應該)。

+0

感謝的人,這正是我一直在尋找! –

+1

瞭解XCAsyncTestCase自述文件中提到的其中一個已知問題是「測試在XCode構建機器人下運行時掛起」可能很有用。所以如果你使用build bot,你可以看iheartradio的'xctest-additions'。 – eremzeit

5

這裏的另一種選擇,XCAsyncTestCase基於GHUnit版本:

https://github.com/iheartradio/xctest-additions

用法是一樣的,只是進口和子XCAsyncTestCase。

@implementation TestAsync 
- (void)testBlockSample 
{ 
    [self prepare]; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(){ 
     sleep(1.0); 
     [self notify:kXCTUnitWaitStatusSuccess]; 
    }); 
    // Will wait for 2 seconds before expecting the test to have status success 
    // Potential statuses are: 
    // kXCTUnitWaitStatusUnknown, initial status 
    // kXCTUnitWaitStatusSuccess, indicates a successful callback 
    // kXCTUnitWaitStatusFailure, indicates a failed callback, e.g login operation failed 
    // kXCTUnitWaitStatusCancelled, indicates the operation was cancelled 
    [self waitForStatus:kXCTUnitWaitStatusSuccess timeout:2.0]; 
}