通过使用XCTestExpectationunit testingasynchronous函数,但它不会等待我设置的秒

我有一个inheritanceNSThreadMyService类:

标题:

 @interface MyService : NSThread { -(void) startMe; -(void) doTask; ... } 

执行:

 @implementation MyService -(void)startMe { [self start]; } -(void) doTask { [self performSelector:@selector(checkData:) onThread:self withObject:nil waitUntilDone:YES]; } -(void) checkData { ... // NOTE: dataChecked is an instance variable. dataChecked = YES; } @end 

我想unit testing上面的-(void)doTask并validation-(void)checkData真的被调用。 我使用OCMock库来部分模拟MyService

受到本教程(使用XCTestExpectation)的启发,我尝试了以下方法:

  -(void) testCheckData { // partial mock MyService id myService = [OCMockObject partialMockForObject:[MyService getInstance]]; [myService startMe]; // function to test [myService doTask]; // I setup expectation XCTestExpectation *expectation = [self expectationWithDescription:@"data checked"]; // run assertion asynchronisely dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ XCTAssertTrue([self isDataChecked]); // expectation fulfill [expectation fulfill]; }); // wait for 5 seconds [self waitForExpectationsWithTimeout:5.0 handler:^(NSError *error) { if (error) { NSLog(@"Timeout Error: %@", error); } }]; } 

但是,当我运行我的testing时, waitForExpectationsWithTimeout:处理程序:不起作用,我的意思是它不等待5秒钟,断言部分立即运行后被testing的函数被调用。 为什么不等5秒?

======更新======

我也试过不使用asynchronous块:

 -(void) testCheckData { // partial mock MyService id myService = [OCMockObject partialMockForObject:[MyService getInstance]]; [myService startMe]; // function to test [myService doTask]; // I setup expectation XCTestExpectation *expectation = [self expectationWithDescription:@"data checked"]; // run assertion XCTAssertTrue([self isDataChecked]); // expectation fulfill [expectation fulfill]; // wait for 5 seconds [self waitForExpectationsWithTimeout:5.0 handler:^(NSError *error) { if (error) { NSLog(@"Timeout Error: %@", error); } }]; } 

但是我仍然得到同样的问题,没有等待5秒,testing马上返回,为什么?

=====和=====

如果我们忽略了上面的更新,并且使用asynchronous代码来查看我的原始代码,我可能会遇到一些问题。我想waitForExpectations:5应该等待我不需要while循环,为什么我认为这种方式是因为那个教程 。

如果查看教程,首先显示使用while循环等待的旧版本 ,然后转换为不使用任何while循环的期望风格,设置期望 – >开始工作(在完成时断言它的工作块),它也有waitForExpectations:代码,看起来与我的代码与asynchronous块完全一样。 我想了解为什么我的原始代码看起来像教程一样,但不起作用。 我想念什么?

一旦你开始waitForExpectations ,你的dispatch_async将有机会运行。 它会断言你的数据已被检查,然后 – 无论你的数据是否被检查过 – 它标志着期望被实现。 一旦完成,我们不再需要等待,我们可以完成。

这可能不是你想要做的,但是这是代码所说的。

好的,解决了。

我应该使用dispatch_after dispatch和dispatch_async ,因为我的testing函数中没有完成块,而本教程中的示例有一个。 所以,我需要改变这个:

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ XCTAssert(...); [expectation fulfill]; }); 

如果你想使用dispatch_async请检查@Avi的注释,在asynchronous块中使用while循环等待。