2013-10-01 30 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]; 
}