Как мне выполнить модульный тест openWithCompletionHandler - PullRequest
1 голос
/ 03 апреля 2012

У меня есть модуль модульного тестирования, полученный из 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 голосов
/ 09 декабря 2012

Эта проблема заняла у меня некоторое время, чтобы понять. Мне нравится модульное тестирование, но при использовании 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];
    }
}
...