我有一个继承 NSThread 的 MyService 类:
标题:
@interface MyService : NSThread {
-(void) startMe;
-(void) doTask;
...
}
实现:
@implementation MyService
-(void)startMe {
[self start];
}
-(void) doTask {
[self performSelectorselector(checkData onThread:self withObject:nil waitUntilDone:YES];
}
-(void) checkData {
...
// NOTE: dataChecked is an instance variable.
dataChecked = YES;
}
@end
我想对上面的 -(void)doTask 进行单元测试并验证 -(void)checkData 是否真的被调用了。我用 OCMock library部分模拟 MyService 。
灵感来自 this tutorial (use 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);
}
}];
}
但是,当我运行测试时,waitForExpectationsWithTimeout:handler:不起作用,我的意思是它不会等待 5 秒,断言部分在被测函数被调用后立即运行。为什么它不等待 5 秒?
====== 更新 ======
我也试过不使用异步 block :
-(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秒,测试立即返回,为什么?
===== AND =====
如果我们忽略上面的更新并返回查看我的原始代码使用异步 block ,我可能会感到很痛苦。我认为 waitForExpectations:5 应该等待我不需要使用 while 循环,为什么我认为这种方式是因为 tutorial .
如果我们查看那个教程,它首先显示了使用while循环的旧风格等待,然后,它变成了不使用任何while循环的期望风格,它所做的是设置期望->开始工作(在其工作的完成 block 中断言),它还有 waitForExpectations: 代码,看起来和我的代码完全一样 with异步 block 。我想了解为什么我的原始代码看起来与教程相同但不起作用。我错过了什么吗?
Best Answer-推荐答案 strong>
一旦您开始waitForExpectations,您的 dispatch_async 就会有机会运行。它会断言您的数据已经过检查,然后——无论你的数据是否已经过检查——它都将期望标记为已实现。一旦完成,我们不再需要等待,我们可以完成。
这可能不是您想要做的,但这就是代码所说的。
关于ios - 使用 XCTestExpectation 对异步函数进行单元测试,但它不会等待我设置的秒数,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/37845892/
|