2012-04-03 3 views
1

У меня есть модуль модульного тестирования, полученный от SenTestCase. Я хотел бы иметь метод единичного теста, который ранее загружал бы полученный документ UIDocument, который я сохранил в изолированной программной среде приложения. Обратите внимание, что этот тест касается загрузки документа локально (iCloud не настроен). Я знаю, что openWithCompletionHandler работает асинхронно, поэтому я понимаю, что это никогда не сработает, как только тестовая функция выйдет из стека. Ниже код дается, чтобы указать свое намерение (конечно, это не работает):Как выполнить модульный тест 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

Теперь я думаю, что есть лучший способ достичь этого. Я понял, что я действительно хочу проверить содержимоеForType и loadFromContents. Поэтому в моем тестовом наборе я создам класс mock, полученный из MyDocument, который будет реализовывать saveToUrl и openWithCompletionHandler, которые будут просто синхронно перенаправлять вызовы contentForType и loadFromContents в MyDocument. Нет смысла иметь дело с файлами ввода-вывода async, если ваша цель - проверить обработку данных в этих методах. Если это исправляет мою проблему, я приду и обновлю этот вопрос. –

+1

Я создал производный класс UIDocument с отображением памяти и производный класс NSMutableData, в котором я завернул свой класс данных, реализующий протокол NSCoding. Я создал несколько делегаций. Но это не сработало. Мне нужно перейти к моему проекту, поэтому я отказываюсь от модульного тестирования UIDocument. Если вы можете указать лучшие стратегии, пожалуйста, сделайте это. Мне все еще интересно узнать. –

ответ

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]; 
    } 
} 
+0

Извините за поздний ответ и очень спасибо @redlightbulb –

Смежные вопросы