2012-03-06 9 views
43

Ho alcuni metodi di utilizzo statico nel mio progetto, alcuni di loro passano o generano un'eccezione. Ci sono molti esempi là fuori su come simulare un metodo statico che ha un tipo di ritorno diverso da vuoto. Ma come posso prendere in giro un metodo statico che restituisce nulla solo a "doNothing()"?Come si simula un metodo statico che restituisce void con PowerMock?

La versione non-vuoto usa queste righe di codice:

@PrepareForTest(StaticResource.class) 

...

PowerMockito.mockStatic(StaticResource.class); 

...

Mockito.when(StaticResource.getResource("string")).thenReturn("string"); 

Tuttavia, se applicata a un StaticResources che restituisce void, la compilazione si lamenterà che when(T) non è applicabile per void ...

Qualche idea?

Una soluzione alternativa sarebbe probabilmente quella di avere tutti i metodi statici per restituire un po 'di Boolean per il successo, ma non mi piace soluzioni alternative.

risposta

25

Puoi farlo nello stesso modo in cui lo fai con Mockito su istanze reali. Per esempio è possibile stub a catena, la seguente riga farà la prima chiamata non fare nulla, poi la seconda e la futura chiamata ad getResources getterà eccezione:

// the stub of the static method 
doNothing().doThrow(Exception.class).when(StaticResource.class); 
StaticResource.getResource("string"); 

// the use of the mocked static code 
StaticResource.getResource("string"); // do nothing 
StaticResource.getResource("string"); // throw Exception 

Grazie ad un'osservazione di Matt Lachman, notare che se il default la risposta non è cambiata al momento della creazione fittizia, il mock non farà nulla per impostazione predefinita. Quindi scrivere il seguente codice equivale a non scriverlo.

doNothing().doThrow(Exception.class).when(StaticResource.class); 
StaticResource.getResource("string"); 

Anche se quello che è detto, può essere interessante per i colleghi che leggerà il test che ci si aspetta nulla per questo particolare codice. Naturalmente questo può essere adattato a seconda di come viene percepita la comprensione del test.


A proposito, a mio modesto parere si dovrebbe evitare beffardo codice statico se il nuovo codice di crafting. A Mockito pensiamo che di solito sia un accenno al cattivo design, potrebbe portare a un codice scarsamente gestibile. Anche se il codice legacy esistente è un'altra storia.

In genere, se è necessario prendere in giro il metodo privato o statico, questo metodo fa troppo e deve essere esternalizzato in un oggetto che verrà iniettato nell'oggetto testato.

Spero che questo aiuti.

saluti

+1

purtroppo, che non funzionerà come quando() accetta solo una variabile e StaticResource è un tipo. ('StaticResource non può essere risolto in una variabile') – Pete

+0

Oh sì, mi spiace, hai ragione, il mio codice è sbagliato, sono abituato ai mock non statici. Ad ogni modo ho aggiornato il mio ansswer per riflettere la sintassi corretta. – Brice

+0

Grazie! Quindi avere metodi di supporto statici che non hanno dipendenze è una cattiva idea? Ovviamente potrei semplicemente iniettare e obiettare che fa il lavoro ma sembra che abbia senso mettere lavoratori che non hanno dipendenze in un oggetto statico per significare la loro indipendenza .. – Pete

55

Puoi stub un metodo static void come questo:

PowerMockito.doNothing().when(StaticResource.class, "getResource", anyString()); 

Anche se non sono sicuro del perché si dovrebbe preoccuparsi, perché quando si chiama mockStatic (StaticResource.classe) tutti i metodi statici in StaticResource sono per default spense

Più utile, è possibile catturare il valore passato a StaticResource.getResource() come questo:

ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); 
PowerMockito.doNothing().when(
       StaticResource.class, "getResource", captor.capture()); 

Poi si può valutare la stringa che è stato passato a StaticResource.getResource in questo modo:

String resourceName = captor.getValue(); 
+0

Essere in grado di fare questo è molto bello perché ti permette di fare cose come il threading.sleep (long millis) per dormire per una quantità diversa di tempo/meno tempo/nessun tempo! – fragorl

+0

C'è un modo per evitare di usare stringhe per i metodi - come "getResource" nel tuo esempio? –

8

In termini più semplici, Immaginate se volete finta sotto la linea:

StaticClass.method(); 

allora si scrive sotto linee di codice a finto:

PowerMockito.mockStatic(StaticClass.class); 
PowerMockito.doNothing().when(StaticClass.class); 
StaticClass.method(); 
1

per deridere un metodo statico che restituiscono vuoto per esempio Fileutils.forceMKdir(File file),

codice di esempio:

File file =PowerMockito.mock(File.class); 
PowerMockito.doNothing().when(FileUtils.class,"forceMkdir",file); 
Problemi correlati