我如何单元测试打开WithCompletionHandler

时间:2012-04-03 10:39:09

标签: ios ios5 objective-c-blocks

我有一个派生自SenTestCase的单元测试模块。我想有一个单元测试方法,可以加载我之前保存在应用程序沙箱中的UIDocument派生文档。请注意,此测试是关于在本地加载文档(未配置iCloud)。我知道openWithCompletionHandler是异步运行的,所以我知道一旦测试函数从堆栈中运行,它就永远不会工作。下面的代码是为了表明我的意图(当然它不起作用):

-(void)testLoadingDocument{
    ...
    MyDocument *document = [[MyDocument alloc] initWithFileURL:destUrl];
    STAssertNotNil(document, @"Document is nil");

    NSLog(@"LOAD: %@", document.fileURL);
    [document openWithCompletionHandler:^(BOOL success) {
        NSLog(@"openWithCompletionHandler success = %@", success);
        if (success) {
            // document.packet will be filled by loadFromContents
            STAssertNotNil(document.packet, @"document.packet is nil.");
        }
    }];
}

我的问题是,有没有办法在单元测试框架内测试openWithCompletionHandler?我不介意是否必须在代码块内同步运行整个文档加载操作。由于这是一个测试代码,我认为这是可以接受的,不像代码必须在设备上异步运行。

非常感谢提前。

1 个答案:

答案 0 :(得分:0)

这个问题花了我一段时间才弄明白。我喜欢单元测试,但是当使用SenTestCase时,您的测试不会在常规代码所在的环境中运行。最重要的是,你缺少一个主循环,其中有一个运行循环,使任何异步回调都容易做任何事情。

那么解决方案是什么?自己提供一个运行循环并使其运行直到调用该块。我们使用在完成块中设置的__block变量来查看何时可以停止运行运行循环。

-(void)testOfAsyncCallingMethod{

    __block bool wasCalled = NO;

    [testingObject methodThatRunsACompletionBlock:^{
        wasCalled = YES;
    }];

    NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:10];
    while (wasCalled == NO && [loopUntil timeIntervalSinceNow] > 0) {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
                                 beforeDate:loopUntil];
    }
}