SenTestingKit в Xcode 4: асинхронное тестирование? - PullRequest
11 голосов
/ 31 мая 2011

Я искал способ использования SenTestingKit для проведения интеграционного тестирования между моим клиентским кодом и нашим сервером. Мне не повезло. Кажется, что когда код запускается в методе, объект уничтожается. Это означает, что любые асинхронные ответы никогда не вызывают селекторы.

Вопросы:

  1. Есть ли способ сохранить объект экземпляром до тех пор, пока я не сочту нужным его уничтожить - т.е. после завершения испытаний?
  2. Если нет, то как я могу создать класс, который блокирует (т.е. действует синхронно) до завершения испытаний?

К вашему сведению, я использую тестовый сервер, на котором я знаю ожидаемые результаты.

Я довольно много погуглил, но так или иначе не видел доказательств по этому поводу. Я уверен, что другим тоже будет интересно.

Ответы [ 5 ]

30 голосов
/ 03 октября 2012

Вы можете использовать семафор для ожидания завершения асинхронного метода.

- (void)testBlockMethod {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    // Your block method eg. AFNetworking
    NSURL *url = [NSURL URLWithString:@"http://httpbin.org/ip"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        NSLog(@"IP Address: %@", [JSON valueForKeyPath:@"origin"]);
        STAssertNotNil(JSON, @"JSON not loaded");
        // Signal that block has completed
        dispatch_semaphore_signal(semaphore);
    } failure:nil];
    [operation start];

    // Run loop
    while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW))
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
                                 beforeDate:[NSDate dateWithTimeIntervalSinceNow:10]];
    dispatch_release(semaphore);

}

http://samwize.com/2012/10/03/sentestingkit-does-not-support-wait-for-blocks/

9 голосов
/ 31 мая 2011

Два варианта:

  • переключиться на GHUnit , который фактически содержит поддержку ожидания асинхронных событий
  • сузьте дизайн ваших тестов, чтобы вы могли тестировать вещи в том виде, в каком они есть. Например. проверьте, что код вашего контроллера вызывает отсоединение и запуск селектора, и (отдельно) проверьте, что этот селектор делает то, что должен. Если обе эти вещи работают, то вы можете быть уверены, что ваш контроллер отключает правильную работу.
3 голосов
/ 26 июля 2013

Этот проект https://github.com/hfossli/AGAsyncTestHelper имеет очень удобный макрос

WAIT_WHILE(<expression_to_evaluate>, <max_duration>);

Что позволяет вам написать тест, как это так

- (void)testDoSomething {

    __block BOOL somethingIsDone = NO;

    [MyObject doSomethingAsyncThenRunCompletionBlockOnMainQueue:^{
        somethingIsDone = YES;
    }];

    WAIT_WHILE(!somethingIsDone, 1.0); 
    NSLog(@"This won't be reached until async job is done");
}
0 голосов
/ 19 августа 2013

Оформить заказ на проект SenTestingKitAsync - https://github.com/nxtbgthng/SenTestingKitAsync. Связанный блог находится здесь - http://www.objc.io/issue-2/async-testing.html

...