Im использует новые возможности асинхронного тестирования Xcode 6. Все работает нормально, когда асинхронная задача заканчивается до таймаута. Но если задача занимает больше времени, чем время ожидания, все усложняется.
Вот как я делаю свои тесты:
@interface AsyncTestCase : XCTestCase @end
@implementation AsyncTestCase
// The asynchronous task would obviously be more complex in a real world scenario.
- (void) startAsynchronousTaskWithDuration:(NSTimeInterval)duration completionHandler:(void (^)(id result, NSError *error))completionHandler
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
completionHandler([NSObject new], nil);
});
}
- (void) test1TaskLongerThanTimeout
{
XCTestExpectation *expectation = [self expectationWithDescription:@"Test 1: task longer than timeout"];
[self startAsynchronousTaskWithDuration:4 completionHandler:^(id result, NSError *error) {
XCTAssertNotNil(result);
XCTAssertNil(error);
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:2 handler:nil];
}
- (void) test2TaskShorterThanTimeout
{
XCTestExpectation *expectation = [self expectationWithDescription:@"Test 2: task shorter than timeout"];
[self startAsynchronousTaskWithDuration:5 completionHandler:^(id result, NSError *error) {
XCTAssertNotNil(result);
XCTAssertNil(error);
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:10 handler:nil];
}
@end
К сожалению, вызов метода fulfill
после истечения тайм-аута завершился с ошибкой с помощью этой ошибки:
Нарушение API - вызвано - [XCTestExpectation выполнить] после завершения контекста ожидания.
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'API violation - called -[XCTestExpectation fulfill] after the wait context has ended.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010c3a6f35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010a760bb7 objc_exception_throw + 45
2 CoreFoundation 0x000000010c3a6d9a +[NSException raise:format:arguments:] + 106
3 Foundation 0x000000010a37d5df -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
4 XCTest 0x0000000115c48ee1 -[XCTestExpectation fulfill] + 264
...
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Конечно, я могу проверить, закончен ли тест до вызова метода fulfill
следующим образом:
- (void) test1TaskLongerThanTimeout
{
XCTestExpectation *expectation = [self expectationWithDescription:@"Test 1: task longer than timeout"];
__block BOOL testIsFinished = NO;
[self startAsynchronousTaskWithDuration:4 completionHandler:^(id result, NSError *error) {
if (testIsFinished) {
return;
}
XCTAssertNotNil(result);
XCTAssertNil(error);
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:2 handler:^(NSError *error) {
testIsFinished = YES;
}];
}
Но это кажется чересчур сложным и делает тест более трудным для чтения. Я что-то упускаю? Есть ли более простой способ решить эту проблему?