0

我正在看这个使用 iOS9 期望使用异步测试的例子。这对于网络请求和其他具有可以满足预期的完成块的操作是有意义的。

但是,我正在尝试对不使用回调块的类进行单元测试。到目前为止,我发现下面的代码在某些时候有效,但我不确定我是否使用了正确的方法。

当应用程序有机会在后台执行某些操作时,如何延迟测试用例?在这种情况下,我可以使用执行选择器在超时之前检查某些内容并满足该后台线程的期望吗?

-(void)checkFoundExpectedSubview:(MockViewController*)mockViewController
{
    if(mockViewController.didFindExpectedSubview)
    {
        [self.expectation fulfill];
    }
}


-(void)testErrorMessage
{
    MockViewController* mockViewController = [MockViewController create];
    [mockViewController expectSubviewWithClass:@"TSMessageView"];

    NSString* title = @"Error!";
    NSString* subtitle = @"This is a unit test of an error message";

    [self.errorHandler reportErrorWithTitle:title message:subtitle];
//this checks and fulfills my expectation
    [self performSelector:@selector(checkFoundExpectedSubview:) withObject:mockViewController afterDelay:2];

    self.expectation = [self expectationWithDescription:@"Waiting for the error to be presented"];

    [self waitForExpectationsWithTimeout:3 handler:^(NSError * _Nullable error) {
        XCTAssertNil(error);
    }];
}
4

1 回答 1

0

您可以使用CFRunLoopRunInMode()等待一段时间,或者直到满足条件。

time_t start = time(NULL);
while (![mockViewController checkFoundExpectedSubview] && time(NULL)-start < 5.0) {
    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, NO);
}
XCTAssertTrue([mockViewController checkFoundExpectedSubview], "Expected something, didn't happen");

上面的代码将一直等待,直到checkFoundExpectedSubview返回 true,或者允许的 5 秒持续时间过去。让运行循环运行意味着允许主线程(队列)处理提交给它的事件和块。

代码可以总结成一个很好的宏:

#define wait(timeout, condition, message) \
{ \
    time_t start = time(NULL); \
    while (!condition && time(NULL)-start < 5.0) { \
        CFRunLoopRunInMode(kCFRunLoopDefaultMode, .1, NO); \
    } \
    XCTAssertTrue(condition, message); \
}

可以这样使用:

wait(5, [mockViewController checkFoundExpectedSubview], "Expected something, didn't happen");
于 2016-01-12T21:24:39.783 回答