Asserire che venga lanciata un'eccezione in JUnit 4 e 5

1. Introduzione

In questo rapido tutorial, vedremo come verificare se è stata generata un'eccezione utilizzando la libreria JUnit.

Ovviamente ci assicureremo di coprire entrambe le versioni JUnit 4 e JUnit 5.

2. JUnit 5

JUnit 5 Jupiter assertions API introduce il metodo assertThrows per affermare le eccezioni.

Questo prende il tipo dell'eccezione prevista e un'interfaccia funzionale eseguibile in cui possiamo passare il codice sotto test tramite un'espressione lambda:

@Test public void whenExceptionThrown_thenAssertionSucceeds() { Exception exception = assertThrows(NumberFormatException.class, () -> { Integer.parseInt("1a"); }); String expectedMessage = "For input string"; String actualMessage = exception.getMessage(); assertTrue(actualMessage.contains(expectedMessage)); }

Se viene generata l'eccezione prevista , assertThrows restituisce l'eccezione, che ci consente di affermare anche sul messaggio.

Inoltre, è importante notare che questa asserzione è soddisfatta quando il codice incluso genera un'eccezione di tipo NullPointerException o uno dei suoi tipi derivati.

Ciò significa che se passiamo Exception come tipo di eccezione prevista, qualsiasi eccezione generata farà sì che l'asserzione abbia esito positivo poiché Exception è il super-tipo per tutte le eccezioni.

Se modifichiamo il test precedente per aspettarci una RuntimeException , anche questo passerà:

@Test public void whenDerivedExceptionThrown_thenAssertionSucceds() { Exception exception = assertThrows(RuntimeException.class, () -> { Integer.parseInt("1a"); }); String expectedMessage = "For input string"; String actualMessage = exception.getMessage(); assertTrue(actualMessage.contains(expectedMessage)); }

Il metodo assertThrows () consente un controllo più dettagliato per la logica di asserzione delle eccezioni perché è possibile utilizzarlointorno a parti specifiche del codice.

3. JUnit 4

Quando si utilizza JUnit 4, è possibile utilizzare semplicemente l' attributo previsto dell'annotazione @Test per dichiarare che ci si aspetta che venga generata un'eccezione ovunque nel metodo di test annotato.

Di conseguenza, quando il test viene eseguito, fallirà se l'eccezione specificata non viene lanciata e passerà se viene lanciata:

@Test(expected = NullPointerException.class) public void whenExceptionThrown_thenExpectationSatisfied() { String test = null; test.length(); }

In questo esempio, abbiamo dichiarato che ci aspettiamo che il nostro codice di test risulti in una NullPointerException .

Questo è sufficiente se ci interessa solo affermare che viene generata un'eccezione.

Quando è necessario verificare alcune altre proprietà dell'eccezione, è possibile utilizzare la regola ExpectedException .

Vediamo un esempio di verifica della proprietà del messaggio di un'eccezione:

@Rule public ExpectedException exceptionRule = ExpectedException.none(); @Test public void whenExceptionThrown_thenRuleIsApplied() { exceptionRule.expect(NumberFormatException.class); exceptionRule.expectMessage("For input string"); Integer.parseInt("1a"); }

Nell'esempio sopra, dichiariamo prima la regola ExpectedException . Quindi, nel nostro test, stiamo affermando che il codice che tenta di analizzare un valore Integer risulterà in un'eccezione NumberFormatException con il messaggio "For input string".

4. Conclusione

In questo articolo, abbiamo trattato la dichiarazione di eccezioni sia con JUnit 4 che con JUnit 5.

Il codice sorgente completo per gli esempi è disponibile su GitHub.