2013-08-14 18 views
7

Ho un oggetto come risultato di una chiamata API e voglio affermare i valori di una variabile membro.È una buona idea catturare AssertionError nei test di JUnit?

Questo valore può essere uno dei due valori previsti a seconda di ciò che l'API chiama "vede" per primo e imposta prima. Quindi, se l'asserzione su un valore fallisce, voglio dichiarare un altro valore prima di dichiarare il test come un fallimento.

Qual è il modo migliore per farlo? Quello che ho adesso è:

try { 
    assertEquals("message", someObject.getValue1(), expectedValue1); 
} catch(AssertionError ae) { 
    assertEquals("message", someObject.getValue1(), expectedValue2); 
} 

Non sono sicuro se questa è una pratica accettabile. Per favore, commenta.

risposta

7

L'utilizzo di eccezioni come una sorta di istruzione gloria goto non è generalmente una buona pratica. O per lo meno ti imbatterai in persone nella tua carriera che non sono d'accordo nell'usare eccezioni per il controllo del flusso del programma.

ne dite:

Assert.assertTrue((someObject.getValue1().equals(expectedValue1) || (someObject.getValue2().equals(expectedValue2)); 
+0

Grazie, @Aquilon! In questo caso, le mie affermazioni sono sepolte in un metodo di verifica che prende come parametri le proprietà dell'oggetto per cui ho bisogno di affermarsi. Quindi non posso davvero passare due valori previsti per la stessa proprietà senza modificare la firma del metodo. Quindi mi sto attenendo al tentativo originale ... prendi la soluzione mentre noti la tua soluzione per il futuro. – Shine

1

Sono d'accordo con Aquilon riguardo a questa di non essere buona pratica.

Tuttavia, è possibile utilizzare il mocking o qualche altro meccanismo per "forzare" l'API "vedere" un elemento prima dell'altro? In questo modo i test possono riflettere le condizioni che portano a un'affermazione vera in un test, e l'altra affermazione è vera in un altro test.

5

Dipende dallo scopo, dal test funzionale automatizzato o dal collaudo dell'unità. A volte mi faccio questo per l'ex:

try { 
    assertTrue(boolean condition from earlier in test method to check); 
} 
catch(AssertionError uhOh) { 
    Logger.err("condition X failed: detailed info msg"); // broken item #1 

} 

try { 
    assertTrue(another condition in same method to check); 
} 
catch(AssertionError yuck) { 
    Logger.err("condition X failed: detailed info msg"); // another broken item 
    fail(); // now blow up as we've checked everything 
} 

Certo che sta usando logback Logger e di JUnit Assert.fail() che fallisce il metodo di prova. In questo modo conosco tutti i fallimenti per questo metodo piuttosto che saltare dopo il primo. Nel mio caso, sto testando un'app web ricca di contenuti (finestre di dialogo e pagine che richiedono molto input da parte dell'utente).

Lo svantaggio di "fail-fast" (senza fermi) sta trovando un problema, risolvendolo, ricominciando e trovandone uno nuovo ("risciacquo e ripetizione"), ma se usato per il collaudo di unità questo è un bene dovuto alla modularità dei test (idealmente si sta testando solo un aspetto di un articolo per test).

Problemi correlati