Как протестировать sendAsynchronousRequest: на XCTest

Извините за вопрос noob, но я пытаюсь проверить соединение, но я не могу проверить возврат запроса, потому что тест заканчивается до того, как обработчик завершения имеет возможность выполнить. Чтобы показать иллюстрацию:

-(void)testConnection
{

    [[Conector sharedInstance] performAsynchronousRequestWithServerRequest:_srvRequest completionHandler:^(RequestAsynchronousStatus finishStatus, NSData *data) {
        if (finishStatus == RequestAsynchronousOK){
            _data = data;
            NSLog(@"Data OK");
        }
    }];

    XCTAssertNotNil(_data, @"Data was nil");

}

Когда я пытаюсь утверждать, _data всегда будет nil, потому что обработчик завершения еще не выполнен. Существует механизм, чтобы заставить тест ждать, пока у меня не будет ответа от метода sendAsynchronousRequest:. Спасибо заранее.

Ответ 1

Это похоже на то, что вам нужно:

XCAsyncTestCase: асинхронный подкласс SenTestCase.

В принципе, вы должны написать свой тест следующим образом:

- (void)testConnection
{
    [[Conector sharedInstance] performAsynchronousRequestWithServerRequest:_srvRequest completionHandler:^(RequestAsynchronousStatus finishStatus, NSData *data) {
        if (finishStatus == RequestAsynchronousOK)
        {
            _data = data;
            [self notify:XCTAsyncTestCaseStatusSucceeded];
            NSLog(@"Data OK");
        }
    }];

    [self waitForTimeout:10];

    XCTAssertNotNil(_data, @"Data was nil");
}

Обратите внимание на вызов waitForTimeout: и notify:. 10 секунд должно быть достаточно для теста, хотя это будет зависеть от самого запроса.

Вы даже можете получить более конкретную информацию и дождаться определенного статуса, например:

[self waitForStatus: XCTAsyncTestCaseStatusSucceeded timeout:10];

Таким образом, если соединение не может уведомить статус XCTAsyncTestCaseStatusSucceeded, вызов ожидания будет тайм-аутом, и ваш тест завершится с ошибкой (как и должно быть).

Ответ 2

Здесь другая альтернатива, XCAsyncTestCase, основанная на версии GHUnit:

https://github.com/iheartradio/xctest-additions

Использование такое же, просто импорт и подкласс XCAsyncTestCase.

@implementation TestAsync
- (void)testBlockSample
{
    [self prepare];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(){
        sleep(1.0);
        [self notify:kXCTUnitWaitStatusSuccess];
    });
    // Will wait for 2 seconds before expecting the test to have status success
    // Potential statuses are:
    //    kXCTUnitWaitStatusUnknown,    initial status
    //    kXCTUnitWaitStatusSuccess,    indicates a successful callback
    //    kXCTUnitWaitStatusFailure,    indicates a failed callback, e.g login operation failed
    //    kXCTUnitWaitStatusCancelled,  indicates the operation was cancelled
    [self waitForStatus:kXCTUnitWaitStatusSuccess timeout:2.0];
}