Start / Seminare / Java Testing mit JUnit, Mockito und Testcontainers

Modul

Verständliche Unit-Tests schreiben

4 Kapitel in diesem Modul-Video · Laufzeit

Vertonung mit synthetischer Stimme · Inhalte redaktionell verantwortet · © 2026 HECKER CONSULTING, alle Rechte vorbehalten

Transkript

Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.

Verständliche Unit-Tests schreiben

0:00 Jetzt schreiben wir Tests. Und ich möchte diesem Modul einen Gedanken voranstellen, der leicht klingt und im Alltag schwer wiegt: Ein Test wird einmal geschrieben und hundertmal gelesen. Fast immer wird er dann gelesen, wenn er rot ist — und meistens von jemandem, der den Code nicht geschrieben hat und wenig Zeit hat. Aus dieser Situation heraus lohnt es sich, über Aufbau, Namen und Assertions nachzudenken.

0:23 Es geht in diesem Modul also nicht um Stilfragen, sondern um die Frage, wie lange die Fehlersuche dauert.

Verständliche Unit-Tests schreiben

0:29 Wir bleiben im ersten Tag und werden konkret. Zuerst der Aufbau eines Tests und seine Benennung, dann die Assertions, und zum Schluss AssertJ und eigene, fachliche Prüfungen. Alles, was hier entsteht, ist die Grundlage für die Datensätze im nächsten Modul.

Aufbau und Benennung eines Tests

0:45 Beginnen wir mit der Struktur. Ein guter Test hat immer dieselbe Form — und wenn er sie nicht hat, ist das fast immer ein Hinweis darauf, dass er zu viel tut. Arrange, Act, Assert — herrichten, handeln, prüfen. Stellen Sie sich ein Kochstudio vor: Zuerst stehen alle Zutaten abgewogen bereit, dann wird gekocht, dann probiert.

1:05 Niemand würde mitten im Kochen noch Zwiebeln schneiden. Given-When-Then ist genau derselbe Aufbau, nur in der Sprache der Fachlichkeit formuliert. Der praktische Nutzen liegt in einer Kontrollfrage: Wenn Sie einen Test nicht in diese drei Abschnitte trennen können, prüft er meist zwei Dinge gleichzeitig. Und ein Test, der zwei Dinge prüft, sagt Ihnen beim roten Lauf nicht, welches der beiden gebrochen ist.

1:30 Achten Sie hier weniger auf den Code als auf die Leerzeilen. Sie sind kein Formatierungsgeschmack, sondern die Lesehilfe: Oben steht der Ausgangszustand, in der Mitte genau eine Handlung, unten genau eine Prüfung. Wer diesen Rhythmus einhält, kann jeden Test in fünf Sekunden erfassen. Zwei Details noch: Der Display Name darf ein ganzer deutscher Satz sein, mit Leerzeichen und Umlauten — den nutzen Sie besser aus.

1:55 Und die Handlung in der Mitte ist eine einzige Zeile. Sobald dort drei Aufrufe stehen, ist unklar, welcher davon geprüft wird. Denken Sie an den Moment, in dem der Build rot wird. Sie sehen zuerst nur eine Zeile: den Namen des Tests. Steht dort „rechneTest2", müssen Sie den Code öffnen. Steht dort „Ab zehn Kisten gilt der Staffelpreis", wissen Sie bereits, welche Regel gebrochen ist — und oft auch schon, wer sie zuletzt angefasst hat.

2:22 Ein guter Name nennt die Bedingung und das erwartete Verhalten. Der schöne Nebeneffekt: Ein so benannter Testbericht lässt sich dem Fachbereich zeigen. Aus einer technischen Ausgabe wird eine Liste geltender Regeln. Diese Gegenüberstellung wirkt wie eine Stilfrage und ist eine Architekturfrage. Links wird nach Methode geschnitten: Jede Methode bekommt ihre Tests, und jede Umbenennung bricht sie.

2:46 Rechts wird nach Verhalten geschnitten: Der Test überlebt das Refactoring, weil er nichts über die Struktur behauptet. Die letzte Zeile sagt, warum das langfristig zählt. Links wächst die Testsuite mit der Klasse — also mit etwas, das sich ständig ändert. Rechts wächst sie mit der Fachlichkeit, und die ändert sich seltener und aus besseren Gründen.

3:06 Der Schnitt entscheidet, ob Ihre Tests eine Regel dokumentieren oder eine Implementierung einbetonieren. Der erste Punkt ist der häufigste Grund für unklare Testberichte: Ein Test prüft drei Dinge, und beim roten Lauf ist unklar, welches. Der zweite ist tückisch — der Aufbau wandert in eine Hilfsmethode, die zehn Zeilen weiter oben inzwischen etwas anderes tut.

3:28 Der dritte ist ein Klassiker mit Spätfolgen: Wer den Ausgangszustand über Felder herstellt statt im Test, riskiert, dass Tests sich gegenseitig beeinflussen — und das fällt erst auf, wenn die Reihenfolge wechselt. Und der vierte ist verschenkte Gelegenheit: Ein Display Name, der nur den Methodennamen wiederholt, trägt nichts bei.

Assertions, die etwas aussagen

3:47 Von der Struktur zur Prüfung. Eine Assertion entscheidet nicht nur, ob ein Test rot wird, sondern auch, wie schnell jemand versteht, warum. Eine Assertion ist eine Erwartung plus eine Fehlermeldung — und der zweite Teil wird gerne vergessen. Jupiter bietet dafür drei Werkzeuge, die über den einfachen Vergleich hinausgehen.

4:07 Mit assertAll bündeln Sie mehrere Prüfungen zu einer, sodass beim roten Lauf alle Abweichungen auf einmal sichtbar werden statt nur die erste. Mit assertThrows prüfen Sie erwartete Ausnahmen. Und mit assertTimeout prüfen Sie Laufzeitgrenzen, ohne selbst Zeitstempel zu nehmen. Der gemeinsame Nenner: Diese Werkzeuge nehmen Ihnen Arbeit ab und geben dafür bessere Meldungen zurück.

4:29 Zwei Muster sind hier wichtig. Oben bündelt assertAll drei Prüfungen unter einem Namen. Der Gewinn zeigt sich im Fehlerfall: Sie sehen alle drei Abweichungen, nicht nur die erste — das spart im Zweifel drei Testläufe. Unten sehen Sie das Detail, das viele übersehen: assertThrows gibt die Ausnahme zurück. Erst dadurch können Sie prüfen, ob es auch die richtige Meldung war.

4:51 Und der wichtigste Rat zu diesem Muster: Umschließen Sie mit assertThrows immer nur die eine Zeile, die werfen soll. Sonst kommt die Ausnahme aus dem Aufbau, und der Test ist grün aus dem falschen Grund. Die Logik hinter dieser Tabelle lässt sich in einem Satz sagen: Überlassen Sie den Vergleich der Assertion. Sobald Sie selbst vergleichen und nur das Ergebnis prüfen, verlieren Sie die Werte in der Fehlermeldung. Und ohne Werte beginnt die Fehlersuche im Debugger statt im Bericht.

5:19 Der Hinweis in der Fußzeile klingt pedantisch, ist aber der Grund für viele irreführende Meldungen: Der erwartete Wert steht links, der tatsächliche rechts. Wer sie vertauscht, bekommt eine Meldung, die genau das Gegenteil behauptet — und sucht dann in der falschen Richtung. Das ist der Kern dieses Kapitels. Wenn Sie einen Vergleich in ein assertTrue stecken, lautet die Meldung im Fehlerfall: erwartet true, war false.

5:43 Diese Meldung ist wahr und vollkommen nutzlos. Überlassen Sie den Vergleich hingegen der Assertion, bekommen Sie beide Werte geliefert. Eine eigene Meldung darf den Kontext ergänzen, aber sie ersetzt niemals den Vergleich. Und noch einmal die Perspektive, die alles entscheidet: Sie schreiben diesen Test für jemanden, der ihn nachts rot vorfindet.

6:03 Was diese Person in der ersten Zeile sieht, bestimmt, ob sie fünf Minuten oder zwei Stunden braucht. Die ersten beiden kennen Sie jetzt: das assertTrue über einem unsichtbaren Vergleich und die vertauschten Werte. Der dritte ist der mit den falschen Erfolgserlebnissen — assertThrows umschließt drei Zeilen, die Ausnahme kam aus der ersten, der Test ist grün, und die eigentliche Regel wurde nie geprüft.

6:26 Der vierte ist der stillste Fehler überhaupt: ein Test ganz ohne Assertion. Er läuft, er ist grün, er erscheint in der Statistik und sichert nichts ab. Solche Tests entstehen selten mit Absicht — meistens beim Umbau, wenn die Prüfung versehentlich herausfällt.

AssertJ und eigene Assertions

6:42 Jetzt kommt eine Bibliothek dazu, die JUnit nicht ersetzt, sondern ergänzt — und die vor allem eines besser macht: erklären, was schiefging. AssertJ arbeitet mit einer Kette: Sie beginnen mit assertThat und dem geprüften Objekt, und ab da schlägt die Bibliothek nur noch Prüfungen vor, die zu diesem Typ passen. Für eine Liste andere als für einen Betrag. Das ist bequem und hat einen zweiten Effekt: Die Fehlermeldungen enthalten den Unterschied, nicht nur die beiden Werte.

7:09 Eigene Assertions gehen einen Schritt weiter — sie bündeln eine wiederkehrende fachliche Prüfung unter einem Namen aus Ihrer Domäne. Aus einer Datenprüfung wird dadurch eine Regel, die man laut vorlesen kann. Die interessante Zeile ist die mit extracting. Ohne sie müssten Sie entweder die Objekte selbst vergleichen — dann brauchen Sie Gleichheit auf Objektebene — oder eine Schleife schreiben.

7:32 Mit extracting sagen Sie: Mich interessiert an dieser Liste nur der Artikelname. Und im Fehlerfall zeigt AssertJ die vollständige Liste beider Seiten. Der zweite Block darunter ist ein Detail mit Sprengkraft: Bei Beträgen vergleichen Sie den Wert und nicht die Darstellung. Zwei Euro fünfzig und zwei Euro fünfzig Komma null sind derselbe Betrag — aber nicht dasselbe Objekt.

7:55 Der Nutzen ist derselbe wie bei jeder guten Abstraktion, nur an einer Stelle, an der man selten abstrahiert. Wiederkehrende Prüfungen bekommen einen Namen aus der Domäne und eine eigene Fehlermeldung. Der Test liest sich danach wie eine Regel, nicht wie eine Datenprüfung. Ändert sich die Regel, gibt es eine Stelle statt vierzig. Und der Preis? Eine Klasse mehr. Meine Faustregel dafür: Ab der dritten Wiederholung lohnt es sich, vorher nicht.

8:21 Wer zu früh abstrahiert, baut eine Assertion, die nur einmal gebraucht wird und trotzdem gepflegt werden muss. Diese drei Zeilen sind das Argument dieses ganzen Kapitels in Kurzform. Dieselbe fachliche Prüfung, drei sehr verschiedene Meldungen. Oben: erwartet true, war false — Sie fangen bei null an. In der Mitte: die beiden Werte — Sie sehen den Unterschied.

8:44 Unten: die Werte und die Abweichung — Sie sehen sofort, dass genau drei Euro fehlen, und wissen vielleicht schon, welche Regel das war. Der Unterschied kostet Sie beim Schreiben nichts. Bemerkbar macht er sich erst, wenn der Test nach einem Jahr das erste Mal bricht — und dann sehr deutlich. Der erste Punkt ist Hausordnung: AssertJ und Jupiter-Assertions in derselben Klasse zu mischen macht sie unruhig — entscheiden Sie sich je Projekt.

9:10 Der zweite ist die überdehnte Abstraktion: Eine eigene Assertion, die zu viel prüft, ist selbst nicht mehr prüfbar und wird zur zweiten Fehlerquelle. Der dritte ist der Betragsvergleich, den wir eben gesehen haben — er erwischt jeden einmal. Und der vierte ist eine Frage des Maßes: Eine Kette über acht Glieder ist beeindruckend zu schreiben und schwer zu lesen. Zwei bis drei Prüfungen sind meist die richtige Länge.

Übung

9:34 Jetzt schreiben Sie selbst — und zwar nicht irgendwelche Tests, sondern die ersten echten Regeln von Krautgut. Zwei Regeln reichen für den Anfang: der Mindestbestellwert und die geschlossenen Liefertage. Ihre Aufgabe ist nicht, möglichst viele Tests zu schreiben, sondern jeden Test so zu bauen, dass Name, Aufbau und Assertion zusammen die Regel dokumentieren.

9:55 Das Erfolgskriterium ist bewusst streng formuliert: Die Fehlermeldung soll zur Diagnose reichen, ohne dass jemand den Code öffnet. Prüfen Sie das ruhig praktisch — lassen Sie einen Test absichtlich brechen und lesen Sie, was im Bericht steht. Das ist die ehrlichste Rückmeldung, die Sie über Ihre eigenen Tests bekommen können.

10:15 Schritt eins ist der ungewohnteste: Schreiben Sie die Regeln als Sätze auf, bevor Sie Testcode tippen. Diese Sätze werden später Ihre Display Names. Schritt zwei setzt sie in Tests um, mit drei sauber getrennten Abschnitten. Schritt drei ist der eigentliche Lerneffekt dieser Übung: Stellen Sie eine Testklasse auf AssertJ um und legen Sie die Fehlermeldungen nebeneinander.

10:36 Und Schritt vier ist die Disziplinfrage — erst bei der dritten Wiederholung entsteht eine eigene Assertion. Nicht bei der ersten, so verlockend das auch ist. Der erste Punkt ist die Abkürzung, die alles entwertet: Die Regeln werden aus dem Code abgelesen statt aus der Fachlichkeit. Dann prüft der Test, dass der Code tut, was er tut.

10:56 Der zweite ist die Zusammenlegung — beide Regeln in einem Test, und schon ist jeder Bruch mehrdeutig. Der dritte ist die zu frühe Abstraktion, wir hatten sie eben. Und der vierte ist der, der am meisten kostet: Der Vergleich der Fehlermeldungen wird übersprungen, weil ja beide Tests grün sind. Genau deshalb sollten Sie einen davon absichtlich rot machen.

Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →