2009-03-30 1 views
22

Sto scrivendo un'applicazione iPhone che richiede di ottenere alcuni dati da un server web. Sto usando NSURLConnection per fare la richiesta HTTP, che funziona bene, ma ho difficoltà a testare il mio codice nel caso in cui la risposta abbia un codice di errore HTTP (come 404 o 500).Test dell'utilizzo di NSURLConnection con gli stati degli errori di risposta HTTP

Sto usando GTM per il test dell'unità e OCMock per il beffardo.

Quando il server restituisce un errore, la connessione non chiama connection:didFailWithError: sulla delegato, ma chiede connection:didReceiveResponse:, connection:didReceiveData: e connectionDidFinishLoading: invece. Al momento sto verificando il codice di stato sulla risposta in connection:didReceiveResponse: e chiamando cancel sulla connessione quando il codice di stato sembra un errore per impedire che venga chiamato connectionDidFinishLoading:, in cui viene segnalata una risposta corretta.

Fornire uno statico con stubing NSURLConnection è semplice, ma voglio che il mio test modifichi il suo comportamento quando viene chiamato uno dei metodi della simulazione. Nello specifico, voglio che il test sia in grado di dire quando il codice ha chiamato cancel sulla connessione simulata, quindi il test può smettere di chiamare connection:didReceiveData: e connectionDidFinishLoading: sul delegato.

Esiste un modo per i test per determinare se è stato chiamato cancel sull'oggetto fittizio? C'è un modo migliore per testare il codice che utilizza NSURLConnection? C'è un modo migliore per gestire gli stati degli errori HTTP?

+0

ti dispiacerebbe mostrare un codice di esempio su come stai testando le chiamate a NSURLConnection? –

risposta

43

Is there a better way to handle HTTP error statuses?

Penso che tu sia sulla strada giusta. Io uso qualcosa di simile al seguente codice, che ho trovato here:

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

Questo annulla la connessione, e chiede connection:didFailWithError: al fine di rendere i codici di errore HTTP si comportano esattamente come qualsiasi altro errore di connessione.

+1

Funziona alla grande. Leggero problema: 'NSHTTPPropertyStatusCodeKey' è deprecato. –

+3

È possibile utilizzare qualsiasi stringa, ad esempio @ "Errore", invece di NSHTTPPropertyStatusCodeKey –

+0

Sì, questo non sembra un uso corretto di "NSHTTPPropertyStatusCodeKey". Cf. il riferimento alla classe NSURL: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/Reference/Reference.html%23//apple_ref/occ/instm/NSURL/relativePath . Inoltre, se sei Xcode 4.4 o successivo, puoi probabilmente abbreviare il codice del dizionario a '@ {NSLocalizedDescriptionKey: [NSHTTPURLResponse localizedStringForStatusCode: statusCode]}'. –