W3docs

Java JUnit Assertions

Verhalten in JUnit 5 prüfen mit assertEquals, assertTrue, assertThrows, assertAll und mehr.

Eine Assertion ist der Moment, in dem ein Test aufhört zu beschreiben und beginnt zu verifizieren — sie gibt an, was der Code produzieren soll, und lässt den Test fehlschlagen, wenn die Realität nicht übereinstimmt. JUnit 5 (die Jupiter-API) fasst alle Assertions als static-Methoden in einer einzigen Klasse zusammen: org.junit.jupiter.api.Assertions. Wenn Sie diese handvoll Methoden kennen, können Sie nahezu jede Erwartung ausdrücken: Gleichheit, Wahrheitswert, Nullheit, Identität, ausgelöste Exceptions, Timeouts und gruppierte Prüfungen. Dieses Kapitel stellt die Methoden vor, die Sie täglich verwenden.

Wenn Sie neu im Framework sind, lesen Sie zuerst die JUnit-Einführung, dann JUnit-Annotationen, um zu sehen, woher @Test-Methoden kommen. Assertions leben innerhalb dieser Methoden.

Das mentale Modell: eine fehlgeschlagene Assertion lässt den Test scheitern

Eine JUnit-Testmethode läuft von oben nach unten. Jede Assertion, die hält, ist lautlos; die erste, die es nicht tut, wirft einen AssertionFailedError, den JUnit abfängt und als Fehler aufzeichnet — die Methode stoppt dort. Assertions sind also die Ausgangspunkte des Tests. Die übliche Argumentreihenfolge ist erwartet zuerst, tatsächlich zweiten, und jede Methode akzeptiert eine optionale abschließende Nachricht, die nur beim Fehlschlag der Prüfung verwendet wird:

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

class CalculatorTest {
  @Test
  void addsTwoNumbers() {
    int result = 2 + 3;
    assertEquals(5, result, "2 + 3 should equal 5");
  }
}

Sie importieren die Methoden statisch (import static ... Assertions.*), damit der Testkörper wie einfaches Englisch gelesen werden kann — assertEquals(...), nicht Assertions.assertEquals(...).

Gleichheit, Wahrheitswert und Nullheit

Diese vier decken die große Mehrheit echter Assertions ab:

MethodeBesteht wenn
assertEquals(expected, actual)expected.equals(actual) ist true
assertNotEquals(unexpected, actual)die beiden sind nicht gleich
assertTrue(condition) / assertFalse(condition)der boolean ist true / false
assertNull(obj) / assertNotNull(obj)die Referenz ist / ist nicht null
assertSame(expected, actual)beide verweisen auf das gleiche Objekt (==)
assertArrayEquals(expected, actual)Arrays sind elementweise gleich
assertEquals("HELLO", "hello".toUpperCase());
assertTrue(List.of(1, 2, 3).contains(2), "list should contain 2");
assertNull(map.get("missing"));
assertNotSame(new String("a"), new String("a")); // distinct objects
assertArrayEquals(new int[]{1, 2, 3}, computeRange(3));

assertEquals verwendet .equals(), also bestehen zwei verschiedene String-Objekte mit denselben Zeichen; assertSame verwendet ==, also scheitern sie. Greifen Sie auf assertSame nur zurück, wenn Objekt-Identität das ist, was Sie testen möchten.

Exceptions testen mit assertThrows

Ein Test behauptet manchmal, dass Code fehlschlägt — dass falsche Eingabe eine Exception wirft. assertThrows nimmt den Exception-Typ und ein Lambda; es besteht nur, wenn das Ausführen des Lambdas diesen Typ (oder einen Untertyp) wirft, und gibt die abgefangene Exception zurück, sodass Sie deren Nachricht prüfen können:

@Test
void rejectsNullName() {
  IllegalArgumentException ex = assertThrows(
      IllegalArgumentException.class,
      () -> greet(null));
  assertEquals("name must not be null", ex.getMessage());
}

Sein Gegenstück ist assertDoesNotThrow, das fehlschlägt, wenn das Lambda irgendetwas wirft — nützlich, um zu bestätigen, dass ein zuvor fehlerhafter Pfad nun sauber läuft. (Für die Regeln, gegen die Ihr Code Exceptions wirft, siehe Java Exceptions.)

Gruppierung mit assertAll

Standardmäßig beendet die erste fehlgeschlagene Assertion die Methode und verbirgt spätere Probleme. assertAll führt jede enthaltene Assertion aus, auch wenn einige scheitern, und meldet dann alle Fehler zusammen — ideal zum Prüfen mehrerer Eigenschaften eines Objekts:

@Test
void buildsCompleteUser() {
  User u = User.of("[email protected]");
  assertAll("user",
      () -> assertEquals("[email protected]", u.email()),
      () -> assertTrue(u.isActive()),
      () -> assertNotNull(u.createdAt()));
}

Wenn sowohl die E-Mail als auch das aktive Flag falsch sind, informiert Sie ein einziger Durchlauf über beides — anstatt eines zu beheben, erneut auszuführen und das nächste zu entdecken.

Ein ausgearbeitetes Beispiel: ein selbstprüfender Testlauf ohne Framework

Der Code-Runner hat kein JUnit im Classpath, deshalb implementiert dieses Programm dieselbe Idee in reinem Java: kleine Hilfsfunktionen assertEquals, assertTrue, assertThrows und assertAll, die sich wie Jupiters verhalten — lautlos bei Erfolg, laut bei Fehler — und eine Handvoll zu testender Methoden steuern und am Ende eine Runner-ähnliche Zusammenfassung ausgeben. Die API, die Sie tatsächlich schreiben würden, steht in den statischen Blöcken oben; dies zeigt, was diese Methoden tun.

java— editable, runs on the server

Was aus dem Lauf zu entnehmen ist:

  • Die bestandenen Prüfungen erzeugen überhaupt keine Fehlerzeilen — nur add(2,3) verified == 5 und tag conditions verified werden ausgegeben, was JUnits Regel widerspiegelt, dass eine erfüllte Assertion lautlos ist und nur Fehler sprechen.
  • assertThrows hat caught expected IllegalArgumentException: name must not be null ausgegeben und zeigt damit das Muster: das Lambda muss eine Exception werfen, der Typ muss übereinstimmen, und die Nachricht der abgefangenen Exception können Sie als Nächstes prüfen.
  • assertAll ran 3 checks, 0 failed bestätigt das Gruppierungsverhalten — alle drei Lambdas wurden ausgeführt und zusammen gezählt, was genau der Grund ist, warum assertAll jedes Problem in einem Durchlauf aufdeckt, anstatt beim ersten zu stoppen.
  • Die abschließende SUMMARY -> passed: 7, failed: 0 zählt sieben einzelne Assertions im gesamten Programm (eine Gleichheit, zwei Booleans, einen Throws und drei innerhalb von assertAll), dieselbe Abrechnung, die ein echter Runner ausgibt — jeder assertX-Aufruf ist eine Verifikation.
  • Hier wurde kein Test-Framework importiert, und dennoch ist die Struktur identisch mit Jupiter: Hilfsfunktionen, die bei Erfolg lautlos und bei Fehler explizit sind. Das Austauschen dieser gegen org.junit.jupiter.api.Assertions.* würde die Imports ändern, nicht die Art und Weise, wie Sie über jede Prüfung nachdenken.
Warnung

Die Argumentreihenfolge verwirrt fast jeden zunächst: es ist assertEquals(expected, actual), niemals umgekehrt. Tauschen Sie sie und der Test funktioniert trotzdem, aber eine Fehlermeldung liest sich verkehrt herum — sie behauptet, Ihr korrekter Wert sei falsch und der fehlerhafte richtig. Halten Sie den wörtlichen oder bekannt-guten Wert an erster Stelle.

Wohin als Nächstes

Assertions sind nur ein Teil einer Testmethode. Um sie effektiv einzusetzen:

  • Gruppieren Sie Setup und Teardown mit den JUnit-Lifecycle-Callbacks (@BeforeEach, @AfterEach).
  • Führen Sie dieselben Assertions über viele Eingaben hinweg ohne Copy-Paste mit parametrisierten Tests aus.
  • Kehren Sie zur Annotationsreferenz für @Test, @DisplayName und @Disabled zurück.

Übung

Übung
Was gibt Ihnen 'assertAll' in JUnit 5, was eine Folge einzelner Assertions nicht bietet?
Was gibt Ihnen 'assertAll' in JUnit 5, was eine Folge einzelner Assertions nicht bietet?
Was this page helpful?