2010-09-09 6 views

risposta

21

@Test(expectedExceptions) è utile per i casi più comuni:

  • ci si aspetta una specifica deroga essere gettato
  • è necessario il messaggio di tale eccezione per contenere parole specifiche

Per la documentazione un test fallirà se non viene lanciato alcun expectedException:

L'elenco di eccezioni che si prevede che un metodo di prova lanci. Se non viene lanciata alcuna eccezione o una diversa da questa lista, questo test verrà contrassegnato come non riuscito.

Ecco alcuni scenari in cui @Test(expectedExceptions) non è sufficiente:

  • tuo metodo di prova ha diverse dichiarazioni e solo si prevede uno di loro di gettare
  • si sta gettando il proprio tipo di eccezione e è necessario assicurarsi che corrisponda un certo criterio

In questi casi, si deve solo tornare al tradizionale (pre-TestNG) modello:

try { 
    // your statement expected to throw 
    fail(); 
} 
catch(<the expected exception>) { 
    // pass 
} 
0

Perché non utilizzare il modello di try/fallire/catture citati nel post del blog si è collegato al?

+0

Quando l'ho visto inizialmente, mi sembrava imbarazzante. Ora che ho sperimentato, sembra che dovrebbe funzionare per quello che sto cercando di fare. –

+0

TestNG si vanta di non doverlo fare. – djechlin

1

Non sono d'accordo con l'articolo sulla natura delle tecniche di prova utilizzate. La soluzione utilizza un gate per verificare se il test deve avere esito positivo o negativo in uno stadio intermedio.

A mio parere, è meglio impiegare Guard Assertions, in particolare per tali test (presupponendo che il test non risulti essere prolisso e complesso, che è un anti-pattern di per sé). Utilizzando guard-asserzioni forze di progettare il SUT in uno dei seguenti modi:

  • disegno il metodo stesso di fornire informazioni sufficienti nel risultato se l'invocazione superato o è riuscito. A volte, questo non può essere fatto in quanto l'intenzione del progettista è di non restituire un risultato, e invece di lanciare un'eccezione (che può essere gestita nel secondo caso).
  • progettare il SUT in modo che sia state can be verified dopo ogni richiamo del metodo significativo.

Ma prima di considerare le possibilità di cui sopra, date un'occhiata al seguente frammento di nuovo:

plane.bookAllSeats(); 
plane.bookPlane(createValidItinerary(), null); 

Se l'intenzione è quella di testare bookPlane() e verificare per l'esecuzione di tale metodo, è meglio avere bookAllSeats() in un dispositivo. A mio avviso, invocare bookAllSeats() equivale a configurare SUT per garantire che l'invocazione di bookPlane() fallisca, e quindi avere un dispositivo per fare lo stesso farebbe un test più leggibile. Se l'intenzione è diversa, consiglierei di testare lo stato dopo ogni transizione (come normalmente farei nei test funzionali), per aiutare a individuare la causa originale dell'insuccesso.

+1

Scopri l'articolo di Christopher collegato a. Questo articolo spiega cosa c'è di sbagliato in esso. Fondamentalmente è che non sai dove è stata lanciata l'eccezione prevista. –

+0

@Thomas, grazie. Ho dovuto leggerlo ancora una volta per capire perché. –

+0

Sono ancora abbastanza nuovo per i test unitari, quindi non ero a conoscenza del concetto di asserzioni di guardia. Grazie per il link! –

0

catch-exception fornisce probabilmente tutto ciò che è necessario verificare per le eccezioni previste.

2
@Test(expectedExceptions = AnyClassThatExtendsException.class, expectedExceptionsMessageRegExp = "Exception message regexp") 

O se non si vuole verificare la presenza di messaggio di eccezione, solo al di sotto è abbastanza

@Test(expectedExceptions = AnyClassThatExtendsException.class) 

In questo modo, non c'è bisogno di utilizzare brutto blocco try catch, basta invocare te metodo di lancio delle eccezioni all'interno del test.