JUnit 5 – Behandlung von Exceptions

JUnit ist ein wichtiges Unit-Test-Framework für die Java Programmiersprache. JUnit ermöglicht das Testen der Ausnahmebehandlung von Code. Es kann also getestet werden, ob der Code eine gewünschte Exception auslöst oder nicht. Es gibt viele Möglichkeiten, mit Ausnahmen umzugehen. Hier werden drei der verbreitetsten Methoden in Junit 4 erläutert und mit den Methoden von Junit 5 verglichen.

1. Try-Catch

Hier ist einer der beliebtesten Ansätze, der bereits in JUnit 3 verwendet wurde:

@Test
public void shouldCheckThrowingArithmeticException() {
   int divided;
   try {
      divided = 1 / 0;
      fail(); // Always to remember to fail test 
              // if no exception thrown 
    }  catch (ArtihmeticException e) {
       assertThrows(e.getMessage(), is("/ by zero")); 
    }
}

Dies ist ein gängiges Beispiel, bei dem die fail() -Methode am Ende des try{} -Blocks hinzugefügt wird. Die fail() -Methode sorgt dafür, dass ein Assertion-Fehler ausgelöst wird, wenn die erwartete Ausnahme nicht im try{} -Block ausgelöst wird.

Dabei ist ein Kritikpunkt von diesem Ansatz zu erwähnen: Wenn vergessen wurde, die fail() -Methode im try{} -Block aufzurufen, wird der Test immer als erfolgreich angesehen.

Um das oben genannte Fehlerrisiko zu vermeiden, können die folgenden Ansätze (JUnit-Rule und Annotation) auf elegante Weise verwendet werden:

2. JUnit Rule

Dieser Ansatz, der auf der Verwendung der ExpectedException-Rule (seit JUnit 4.7) mit Annotation @Rule basiert, testet sowohl den Ausnahmetyp als auch die Exception Message:

@Rule
private ExpectedException expected = ExpectedException.none();

@Test
public void shouldCheckThrowingArithmeticException() {
       expected.expect(ArtihmeticException.class); 
       expected.expectMessage("/ by zero");
       int divided = 1 / 0;
}

Wenn die erwartete Ausnahme nicht geworfen wird, wird die folgende Meldung angezeigt:

3. Annotation

Der Annotation-Ansatz kann erfolgreich verwendet werden, wenn nur der Typ der Ausnahme überprüft werden soll.

Hier ist ein Beispiel für diesen Ansatz, wobei die auszulösende Ausnahme in der @Test-Annotation definiert wird:

@Test(expected = ArtihmeticException.class)
public void shouldCheckThrowingArithmeticException() {
        int divided = 1 / 0;
}

Hier ist die Ausgabe dieser Variante, wenn die erwartete Exception nicht ausgelöst wird:

Die Vorteile der beiden letzten Ansätze sind:

  • Automatische Ausgabe von Fehlermeldungen, wenn keine Ausnahme geworfen wurde
  • Bessere Lesbarkeit des Codes
  • Man muss weniger Code schreiben

4. Testen von Exceptions mit JUnit 5

Junit 5 bietet eine elegantere Vorgehensweise dank der assertThrows() -Methode für Ausnahmebehandlung. Bei dieser Methode kann der zu testende Code über einen Lambda-Ausdruck übergeben werden:

@Test
@DisplayName("Testing NullPointerException")
public void shouldThrowNullPointerException() {
     String test = null;  
     Assertions.assertThrows(NullPointerException.class, () -> {
        test.length();
     }); 
}

Außerdem kann hier Exception.class als erwarteter Ausnahmetyp übergeben werden, da Exception.class der übergeordnete Typ für alle Ausnahmen ist:

@Test
@DisplayName("Testing NullPointerException")
public void shouldThrowNullPointerException() {
     String test = null;  
     Assertions.assertThrows(Exception.class, () -> {
        test.length();
     }); 
}
Short URL for this post: https://wp.me/p4nxik-3vv
This entry was posted in Java and Quality and tagged , , . Bookmark the permalink.

Leave a Reply