使用 XCTestExpectation 单元测试异步函数,但它不会等待我设置的秒数 [英] unit test async function by using XCTestExpectation but it doesn't wait for the seconds I set
问题描述
我有一个继承 NSThread
的 MyService
类:
I have a MyService
class which inherits NSThread
:
标题:
@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
我想对上面的 -(void)doTask
进行单元测试并验证 -(void)checkData
是否真的被调用了.我使用 OCMock 库 部分模拟 MyService代码>.
I want to unit test the above -(void)doTask
and verify that -(void)checkData
is really called. I use OCMock library to partially mock MyService
.
受到本教程(使用 XCTestExpectation) 的启发,我尝试了以下方法:
Inspired by this tutorial (use XCTestExpectation), I tried the following way:
-(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 秒?
However, when I run my test, the waitForExpectationsWithTimeout:handler: doesn't work, I mean it doesn't wait for 5 seconds, the assertion part run immediately after function under test get called. Why it doesn't wait 5 seconds?
====== 更新 ======
我也试过不使用异步块:
I also tried not using async 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秒,测试立即返回,为什么?
But I still get the same problem, there is no waiting 5 seconds, the test return immediately, why?
===== AND ======
我可能会抱怨,如果我们忽略上面的更新 &返回查看我的原始代码使用异步块.我认为 waitForExpectations:5
应该执行我不需要使用 while
循环的等待,为什么我这么认为是因为教程.
I might be wroing, if we ignore my update above & back to see my original code using async block.I think waitForExpectations:5
should do the waiting that I don't need to use while
loop, why I think this way is because of that tutorial.
如果我们检查那个教程,它首先显示使用while循环的旧风格等待,然后,它变成了不使用任何while循环的期望风格>,它所做的是设置期望->开始工作(在其工作的完成块中断言),它还有waitForExpectations:
代码,它看起来和我的代码完全一样异步块.我想了解为什么我的原始代码看起来与教程相同但不起作用.我错过了什么吗?
If we check that tutorial, it firstly show the old stye of using while loop to wait, then, it changed to expectation style which doesn't use any while loop, what it does is set expectation->start work ( assert in the completion block of its work), it also has the waitForExpectations:
code, which looks exactly the same as my code with the async block. I want to understand why my original code looks the same as the tutorial but doesn't work. Do I miss something?
推荐答案
好的,解决了.
我应该使用 dispatch_after
代替 dispatch_async
,因为我的测试函数中没有完成块,而该教程中的示例有一个.所以,我需要改成这样:
I should use dispatch_after
insteand of dispatch_async
, because I don't have a completion block in my function under test while the example in that tutorial has one. So, I need to change to this:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
XCTAssert(...);
[expectation fulfill];
});
如果你想使用 dispatch_async
请查看@Avi 的评论,在异步块中使用 while
循环等待.
If you want to use dispatch_async
please check @Avi's comment, use a while
loop in the async block to wait.
这篇关于使用 XCTestExpectation 单元测试异步函数,但它不会等待我设置的秒数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!