通过使用XCTestExpectationunit testingasynchronous函数,但它不会等待我设置的秒
我有一个inheritanceNSThread
的MyService
类:
标题:
@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
循环等待。