我有一个派生自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
?我不介意是否必须在代码块内同步运行整个文档加载操作。由于这是一个测试代码,我认为这是可以接受的,不像代码必须在设备上异步运行。
非常感谢提前。
答案 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];
}
}