2011-09-05 19 views
5

Sto testando le chiamate di servizi Web reali con OCMock.Verifica OCMock ritardata/Gestione del timeout nei test delle unità

In questo momento sto facendo qualcosa di simile:

- (void)testWebservice 
{ 
    id mydelegatemock = [OCMockObject mockForProtocol:@protocol(MySUTDelegate)]; 
    [[mydelegatemock expect] someMethod:[OCMArg any]]; 

    [SUT sutWithDelegate:mydelegatemock]; 

    // we need to wait for real result 
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]]; 

    [(OCMockObject*)mydelegatemock verify]; 
} 

Funziona bene, ma implica che ogni tale prova avrà 2 secondi.

C'è un modo per impostare un timeout di ad es. 2 secondi e lasciare una chiamata a someMethod di mydelegatemock immediatamente verify e completare il test case?

risposta

5

mi fare questo utilizzando una funzione di programma di utilità pratico ho trovato at this link:

#import <Foundation/Foundation.h> 
#import <OCMock/OCMock.h> 

@interface TestUtils : NSObject 
+ (void)waitForVerifiedMock:(OCMockObject *)mock delay:(NSTimeInterval)delay; 
@end 

e l'implementazione:

#import "TestUtils.h" 
@implementation TestUtils 

+ (void)waitForVerifiedMock:(OCMockObject *)inMock delay:(NSTimeInterval)inDelay 
{ 
    NSTimeInterval i = 0; 
    while (i < inDelay) 
    { 
     @try 
     { 
      [inMock verify]; 
      return; 
     } 
     @catch (NSException *e) {} 
     [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]]; 
     i+=0.5; 
    } 
    [inMock verify]; 
} 

@end 

Questo mi permette di attendere fino a un ritardo massimo (in secondi), senza aspettando l'intero importo ogni volta.

+2

Forse origine qui? ... http://touchalicious.com/blog/2009/11/5/asynchronous-unit-testing-with-ocmock.html –

+1

Grazie Max - sembra la fonte. Ho aggiornato la risposta originale con un collegamento all'originale. –

1

Vorrei separare il test funzionale dei servizi Web (se necessario per farlo) dal test dell'unità della classe che elabora il risultato del servizio web.

Per il test dell'unità, è necessario prendere in giro la chiamata al servizio web, fornendo un risultato simulato. Quindi il tuo test verificherebbe che, per quel risultato ben definito, la tua classe si comporti di conseguenza.

Se si desidera eseguire anche test funzionali del proprio servizio Web (ad esempio che restituisce una risposta specifica in base ad alcune richieste), non è necessario prendere in giro nulla: basta chiamare il servizio e fare asserzioni sul risultato.

Separando i test, si ottiene un controllo più preciso sulle esecuzioni di test. Ad esempio, è possibile eseguire i test di unità in esecuzione rapida ogni volta che si modifica il codice, ma eseguire i test di funzionamento lento ogni notte, su un server dedicato o secondo necessità. E quando un test si interrompe, saprai se è il tuo codice o qualcosa di sbagliato nel servizio web.

+2

Ho già eseguito test predefiniti con ritorni falsi immediati dal servizio web. Questa domanda riguardava i test di integrazione con il vero servizio web. Ammetto che avrei potuto lasciare la parte della domanda in parte in quelle, ma non cambia il fatto che devo aspettare il risultato in qualche modo. E: con i risultati predefiniti, non testare la latenza tra richiesta e risultato, come nel caso dei risultati predefiniti, in realtà il delegato risultato viene chiamato * prima * che la richiesta è terminata. – fabb

Problemi correlati