Тестирование использования NSURLConnection со статусами ошибок ответа HTTP - PullRequest
22 голосов
/ 30 марта 2009

Я пишу приложение для iPhone, которое должно получать данные с веб-сервера. Я использую NSURLConnection для выполнения HTTP-запроса, который работает хорошо, но у меня возникают проблемы с модульным тестированием моего кода в случае, когда ответ имеет код ошибки HTTP (например, 404 или 500).

Я использую GTM для юнит-тестирования и OCMock для насмешек.

Когда сервер возвращает ошибку, соединение не вызывает connection:didFailWithError: для делегата, а вместо этого вызывает connection:didReceiveResponse:, connection:didReceiveData: и connectionDidFinishLoading:. В настоящее время я проверяю код состояния в ответе в connection:didReceiveResponse: и вызываю cancel в соединении, когда код состояния выглядит как ошибка, препятствующая вызову connectionDidFinishLoading:, когда будет получен успешный ответ.

Предоставить статическую заглушку NSURLConnection очень просто, но я хочу, чтобы мой тест изменил свое поведение при вызове одного из методов фиктивного соединения. В частности, я хочу, чтобы тест мог определить, когда код вызвал cancel в фиктивном соединении, поэтому тест может прекратить вызывать connection:didReceiveData: и connectionDidFinishLoading: для делегата.

Есть ли способ для тестов определить, вызван ли cancel для фиктивного объекта? Есть ли лучший способ проверить код, который использует NSURLConnection? Есть ли лучший способ обработки статусов ошибок HTTP?

1 Ответ

43 голосов
/ 24 апреля 2009

Есть ли лучший способ обработки статусов ошибок HTTP?

Я думаю, вы на правильном пути. Я использую что-то похожее на следующий код, который я нашел здесь :

if ([response respondsToSelector:@selector(statusCode)])
{
    int statusCode = [((NSHTTPURLResponse *)response) statusCode];
    if (statusCode >= 400)
    {
        [connection cancel];  // stop connecting; no more delegate messages
        NSDictionary *errorInfo
          = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:
            NSLocalizedString(@"Server returned status code %d",@""),
            statusCode]
                                        forKey:NSLocalizedDescriptionKey];
        NSError *statusError
          = [NSError errorWithDomain:NSHTTPPropertyStatusCodeKey
                                code:statusCode
                            userInfo:errorInfo];
        [self connection:connection didFailWithError:statusError];
    }
}

Это отменяет соединение и вызывает connection:didFailWithError:, чтобы заставить коды ошибок http вести себя точно так же, как любая другая ошибка соединения.

...