CodeGym /Kurse /Spring Test /Fehler beim Lesen von Anfragen in Spring MVC

Fehler beim Lesen von Anfragen in Spring MVC

Spring Test
Level 12, Lektion 1
Verfügbar

1. DTO vs fehlerhafte Anfrage

Wenn JSON gelesen und das DTO erstellt wurde, kennen wir bereits die nächste Frage: Wird das Objekt die Bean Validation bestehen? Jetzt betrachten wir eine andere Klasse von Problemen – Situationen, in denen die Anfrage nicht einmal ordnungsgemäß zusammengestellt werden konnte. Dies ähnelt dem Unterschied zwischen „Sie kommen zur Bank ohne die erforderlichen Dokumente“ und „Sie kommen, aber der Antrag ist falsch ausgefüllt“: In beiden Fällen werden Sie abgewiesen, aber der Vorgang scheitert in unterschiedlichen Schritten – und der Test muss dies unterscheiden.

Die Validierung (@Valid) beginnt erst, wenn Spring den Body lesen, JSON parsen und ein DTO erstellen konnte. Malformed JSON und Type Mismatch hingegen unterbrechen die Anfrage früher: beim Lesen des Bodys oder bei der Parameterkonvertierung. Das Ergebnis für den Client sieht oft gleich aus (400 Bad Request), und genau deshalb ist es sehr leicht, einen Test „am Thema vorbei“ zu schreiben und ein grünes Ergebnis zu erhalten, das nichts beweist.

Halten wir dies in einer kleinen Tabelle fest. Sie handelt nicht von „allen Statuscodes der Welt“, sondern speziell davon, die Verarbeitungsschritte nicht zu verwechseln:

Situation JSON syntaktisch OK? DTO erstellt? Bean Validation wird gestartet? Controller-Methode wird wirklich aufgerufen? Typisches Ergebnis
Validation failure (@NotBlank, @Size) ja ja ja nein 400
Malformed JSON (defekte Syntax) nein nein nein nein 400
Message conversion failure (JSON OK, aber nicht auf DTO abbildbar) ja nein nein nein 400
Type mismatch (z. B. id=abc für Long) egal egal nein nein 400

Für das Szenario @RequestBody + @Valid, auf dem diese Ebene basiert, wird die Handler-Methode ebenfalls nicht aufgerufen: MethodArgumentNotValidException tritt bereits während der Argumentvorbereitung auf. Andere Varianten der Methodenvalidierung lassen wir jetzt außen vor, um verschiedene Mechanismen nicht zu vermischen.

Die letzte Spalte („typisches Ergebnis“) wurde bewusst vorsichtig formuliert. Wir bauen hier keine „Statuscode-Religion“ auf; wichtiger ist zu verstehen, warum die Anfrage nicht durchkommt und auf welcher Stufe sie scheitert. Das wird Gegenstand unserer MVC-Tests sein.

2. Wo eine Anfrage in Spring MVC scheitert

Um präzise Negativtests zu schreiben, ist es hilfreich, die Anfrageverarbeitung als Pipeline zu betrachten. Spring MVC „teleportiert“ JSON nicht direkt in Ihre Controllermethode – es durchläuft eine Abfolge von Schritten: Handler-Auswahl, Konvertierung der Parameter, Lesen des Bodys, Erstellen des DTOs, Starten der Validierung. Wenn der Test nicht versteht, in welchem Schritt der Fehler aufgetreten ist, prüft er leicht zufällige Symptome statt der Ursache.

Vereinfachen wir die Pipeline auf ein für den Testautor ausreichendes Niveau (ohne in Hunderte von internen Klassen einzutauchen). In der Realität gibt es mehr Schritte, aber für die heutigen Fehlerarten sind folgende Punkte relevant:

flowchart TD
    A[HTTP Request] --> B[HandlerMapping wählte Controller-Methode]
    B --> C[Konvertierung der Methodenargumente]
    C --> C1["@PathVariable / @RequestParam String->Long/Enum/…"]
    C --> C2["@RequestBody HttpMessageConverter + Jackson"]
    C2 --> D[Binding: DTO zusammenstellen]
    D --> E["Bean Validation: @Valid"]
    E --> F[Aufruf der Controller-Methode]
    F --> G[Controller ruft Service auf]
    G --> H[HTTP Response]

    C1 -. type mismatch .-> X[400]
    C2 -. malformed JSON / conversion failure .-> X[400]
    E -. constraint violations .-> X[400]

Beachten Sie den heiklen Punkt: Verschiedene Fehler münden im selben Status 400, scheitern aber an unterschiedlichen Stellen. Die Validierung ist bereits die Zielgerade vor dem Methodenaufruf. Malformed JSON bedeutet „nicht einmal am Eingang zum DTO angekommen“. Type Mismatch liegt noch früher: Selbst die Methodenargumente (z. B. Long id) konnten nicht zusammengestellt werden.

Die praktische Konsequenz für Tests ist sehr einfach, aber nützlich: Wenn der Fehler in einer frühen Phase auftritt, darf Ihr service überhaupt nicht aufgerufen werden. Und das ist eine gute, klare und recht stabile Assertion, die uns vor einem zufälligen „Fehltest“ schützt.

3. Malformed JSON und nicht lesbarer Body

Der Request-Body ist der Ort, an dem Entwickler am häufigsten das Gefühl haben: „Ich habe doch JSON gesendet, warum ist Spring nicht zufrieden?“. Der Grund liegt meist darin, dass der JSON entweder syntaktisch defekt ist oder syntaktisch korrekt, aber nicht in Ihr DTO deserialisiert werden kann (z. B. ein Feld erwartet einen String, es kommt aber eine Zahl). In beiden Fällen wird @Valid nicht gestartet, weil kein DTO entstanden ist – Spring hat nichts zu validieren.

Malformed JSON: Defekte Syntax

Malformed JSON bedeutet, dass der Request-Body überhaupt nicht als JSON geparst werden kann. Typische Beispiele: eine geschweifte Klammer nicht geschlossen, ein Anführungszeichen vergessen, ein Komma an der falschen Stelle, JSON „fast wie in JavaScript“ (aber JSON mag das nicht).

In ContentHub tritt dies häufig bei Editor-Endpunkten auf:

  • POST /api/editor/articles (Entwurf erstellen),
  • PUT /api/editor/articles/{id} (Aktualisieren).

Für den Test benötigen wir keine aufwändige Vorbereitung: Es reicht, einen offensichtlich defekten JSON zu senden und zu prüfen, ob wir 400 erhalten und der Service nicht aufgerufen wird.

@Test
void shouldReturn400_whenJsonIsMalformed() throws Exception {
    // Syntaktisch defekter Body: geschweifte Klammer nicht geschlossen
    String body = """
        {"title":"A"
        """;

    mvc.perform(post("/api/editor/articles")
            // Wichtig: Wir testen explizit das JSON-Lesen, daher ehrlicher Content-Type
            .contentType(MediaType.APPLICATION_JSON)
            .content(body))
        .andExpect(status().isBadRequest());

    // Marker, dass die Anfrage VOR Controller/Service (beim Body-Lesen) gescheitert ist
    then(service).shouldHaveNoInteractions();
}

Hier sind zwei Gedanken wichtig. Erstens: Wir setzen explizit Content-Type: application/json, sonst könnte der Fehler ein anderer sein (z. B. 415), und der Test prüft nicht das, was wir beabsichtigen. Zweitens: shouldHaveNoInteractions ist unser Marker, dass die Pipeline nicht einmal zur Service-Schicht gelangt ist.

Manchmal ist es nützlich sicherzustellen, dass wir wirklich einen „Body-Lese-Fehler“ gefangen haben und nicht etwa eine Bean Validation. Dazu können wir den Ausnahmetyp prüfen, den Spring innerhalb von MVC behandelt hat.

import static org.assertj.core.api.Assertions.assertThat;

@Test
void shouldExposeHttpMessageNotReadableException_forMalformedJson() throws Exception {
    mvc.perform(post("/api/editor/articles")
            .contentType(MediaType.APPLICATION_JSON)
            // Minimaler “defekter” JSON: Objekt geöffnet, aber nicht geschlossen
            .content("{"))
        .andExpect(result -> assertThat(result.getResolvedException())
            // Prüfen explizit auf Body-Lese-Fehler (nicht auf @Valid-Fehler)
            .isInstanceOf(HttpMessageNotReadableException.class));
}

Das ist nicht für jeden Test zwingend erforderlich, aber als „Absicherung gegen Verwechslungen“ in einem Lernprojekt sehr nützlich. Insbesondere, wenn Sie noch daran arbeiten, verschiedene Klassen negativer Szenarien nicht zu vermischen.

JSON valide, aber DTO nicht erstellbar

Es gibt eine kniffligere Situation: Der JSON ist syntaktisch korrekt, aber Jackson kann kein DTO erzeugen. Ein lebensnahes Beispiel: Das Feld title erwartet einen String, Sie senden aber eine Zahl. Oder das Feld category im DTO ist ein Enum, Sie senden aber einen nicht existierenden Wert.

Für Spring ist das immer noch ein „Body-Lese-Fehler“: Es versucht den Body zu lesen und in ein Objekt zu verwandeln, kann es aber nicht. Oft endet dies wieder mit HttpMessageNotReadableException (mit einer inneren Ursache, z. B. MismatchedInputException).

@Test
void shouldReturn400_whenJsonCannotBeMappedToDto() throws Exception {
    // JSON syntaktisch korrekt, aber der Typ des Feldes "title" passt nicht zum DTO (String erwartet)
    String body = """
        {"title":123,"summary":"S","body":"B","category":"JAVA"}
        """;

    mvc.perform(post("/api/editor/articles")
            .contentType(MediaType.APPLICATION_JSON)
            .content(body))
        .andExpect(status().isBadRequest());

    // DTO wurde nicht erstellt -> Geschäftslogik wurde nicht erreicht
    then(service).shouldHaveNoInteractions();
}

Warum ist es wichtig, dies separat von der Bean Validation zu behandeln? Denn bei einem Validation-Failure erwarten Sie, dass das DTO erstellt wurde, und die Fehler beziehen sich auf die Felder: leere Zeichenkette, zu lang, falsches Format. Hier wurde das DTO nicht geboren – und Sie sollten nicht vom Antwortobjekt verlangen, z. B. eine Liste von violations im Format feldbezogener Fehler zu enthalten. In einer guten API kann man einen einheitlichen Error-Vertrag erstellen, aber das ist eine bewusste, separate Entscheidung; standardmäßig ist der Mechanismus ein anderer.

Leerer Request-Body

Ein weiterer realistischer Fall: Der Client sendet Content-Type: application/json, aber der Body ist leer. Aus menschlicher Sicht wirkt das wie „Ich habe doch eine Anfrage gesendet“, aus Springs Sicht: „Ich habe nichts zu lesen, und @RequestBody ist erforderlich“.

@Test
void shouldReturn400_whenRequestBodyIsEmpty() throws Exception {
    mvc.perform(post("/api/editor/articles")
            // Content-Type vorhanden, aber Payload leer
            .contentType(MediaType.APPLICATION_JSON)
            .content(""))
        .andExpect(status().isBadRequest());

    // Fehler auf der Web-Ebene: Der Service sollte nicht gestartet werden
    then(service).shouldHaveNoInteractions();
}

In realen Projekten tritt ein leerer Body oft nicht auf, weil der Client „böswillig“ ist, sondern weil die Integration defekt ist: Irgendwo wurde vergessen, das Objekt zu serialisieren, der falsche Stream gesendet, oder der Payload ging in einem Proxy verloren. Daher ist ein Test für dieses Szenario weder Luxus noch Schikane, sondern ein Weg, das API-Verhalten vorhersagbar zu machen.

4. Type mismatch bei Parametern

Wenn wir einen Endpunkt wie GET /api/editor/articles/{id} sehen, denkt man sofort an „Artikel gefunden / nicht gefunden“. Aber davor gibt es eine grundlegendere Frage: Ist id überhaupt eine Zahl? Wenn Sie ein Long id erwarten, im URL aber abc ankommt, dann ist das nicht „Artikel nicht gefunden“. Es ist: „Der Client hat einen Parameter mit falschem Typ gesendet“. Und das scheitert bereits vor der Artikelsuche und vor dem Serviceaufruf.

In ContentHub sind solche Szenarien besonders wichtig für Editor/Admin-APIs, da dort viele IDs vorkommen: article id, attachment id usw.

Aus Controllersicht sieht das (stark vereinfacht) so aus:

@GetMapping("/api/editor/articles/{id}")
ArticleDetailsResponse getById(@PathVariable Long id) {
    // Zu diesem Zeitpunkt muss id bereits ein Long sein.
    // Wenn "abc" kommt, erreicht die Anfrage die Controller-Methode gar nicht.
    return service.getById(id);
}

Wenn statt einer Zahl ein String kommt, versucht Spring ihn in Long zu konvertieren (über Converter/Binding), kann es nicht und liefert 400. Es gibt keine „Suche nach ID“ – es gab nichts zu suchen.

Falscher Typ einer Path Variable

Der Test wird sehr kurz – und das ist gut. Unser Ziel ist es, die Semantik festzuschreiben: falscher Eingabetyp → 400, Service wird nicht angerührt.

@Test
void shouldReturn400_whenIdIsNotLong() throws Exception {
    // In der Path Variable kommt ein nicht-numerischer Wert
    mvc.perform(get("/api/editor/articles/abc"))
        .andExpect(status().isBadRequest());

    // Die Argumentkonvertierung scheiterte vor dem Aufruf von Controller/Service
    then(service).shouldHaveNoInteractions();
}

Wenn man „beweisen“ möchte, dass es sich um einen Type Mismatch handelt, kann man die resolved exception prüfen. Bei Path Variables taucht häufig MethodArgumentTypeMismatchException auf.

@Test
void shouldFailWithTypeMismatchException_whenIdIsNotLong() throws Exception {
    mvc.perform(get("/api/editor/articles/abc"))
        .andExpect(result -> assertThat(result.getResolvedException())
            // assertThat – aus AssertJ; normalerweise static import im Test
            .isInstanceOf(MethodArgumentTypeMismatchException.class));
}

Auch das ist keine Pflicht für jeden Test. Aber als Lern- und Debugging-Werkzeug hilft es hervorragend, die Typen negativer Fälle nicht zu verwechseln.

Semantik: Das ist kein 404

Hier schlägt oft die „Benutzerintuition“ zu: Da der Artikel unter abc nicht gefunden wird, müsse es 404 sein. Aber der Server kann ehrlich nicht sagen „Ressource nicht gefunden“, weil die Ressource in dieser Form gar nicht existiert, theoretisch nicht einmal. id ist per Vertrag eine Zahl; abc ist keine „nicht vorhandene ID“, es ist „keine ID“.

In Tests ist das wichtig, weil man sonst beginnt, negative Szenarien um den Service herum zu bauen (z. B. given(service.getById(...)).willThrow(...)), obwohl der Service gar nicht aufgerufen werden sollte. Das wäre dann ein Test „über Ihre Fantasie“, nicht über das API-Verhalten.

5. Header und 415 Unsupported Media Type

Es ist sehr leicht, einen Test zu schreiben, der „irgendwie JSON sendet“, aber vergisst, den Content-Type zu setzen. Oder einen falschen Content-Type setzt, z. B. text/plain. Für einen Menschen ist das dasselbe: „Ich habe doch den JSON in den Body gelegt“. Für Spring MVC sind das unterschiedliche Fälle, weil die Auswahl des HttpMessageConverter vom Header Content-Type abhängt. Und dann erhalten Sie statt des erwarteten 400 plötzlich 415 Unsupported Media Type und schimpfen eine halbe Stunde auf Jackson, weil er „nicht parst“.

Wenn Ihre Controller-Methode @RequestBody akzeptiert, sucht Spring nach einem Converter, der genau diesen Media-Typ lesen und in den erforderlichen Java-Typ umwandeln kann. Wenn kein Converter gefunden wird, ist das normalerweise 415.

Nicht unterstützter Content-Type

Hier ist ein Test, der Entwickler oft überrascht: Der JSON-String ist da, aber der Header sagt text/plain.

@Test
void shouldReturn415_whenContentTypeIsTextPlain() throws Exception {
    // Body sieht aus wie JSON, aber der Content-Type passt nicht zu @RequestBody JSON
    String body = """
        {"title":"T"}
        """;

    mvc.perform(post("/api/editor/articles")
            .contentType(MediaType.TEXT_PLAIN)
            .content(body))
        .andExpect(status().isUnsupportedMediaType());

    // Der Service wird nicht erreicht: Kein passender HttpMessageConverter gefunden
    then(service).shouldHaveNoInteractions();
}

Daraus ergibt sich eine praktische Regel für MVC-Tests: Wenn ein Test das Lesen einer Anfrage prüft, muss er HTTP-ehrlich sein. Das heißt, er setzt die Header, die ein realer Client setzen würde, und zeigt explizit, welcher Fall getestet wird.

Fehlender Content-Type

Wenn Content-Type vollständig fehlt, hängt das Ergebnis von der Konfiguration und den Details der Anfrage ab, aber sehr oft führt auch dies zu 415. Denn Spring weiß nicht, mit welchem Converter der Body gelesen werden soll.

In Übungstests sollte man nicht „Ratespiel“ spielen: Wenn wir JSON-Parsing testen wollen, setzen wir explizit application/json. Wenn wir das Verhalten bei falschem Content-Type testen wollen, setzen wir den falschen Content-Type und erwarten den entsprechenden Status.

6. Testvorlage in @WebMvcTest

Bei Negativtests besteht die Versuchung, schnell viele fast identische Methoden zu schreiben, bei denen nur ein Zeichen im JSON und eine Assertion geändert wird. Nach ein paar Tagen wird daraus ein unübersichtliches Durcheinander: Man versteht nicht mehr, was genau die Anfrage scheitern lässt und warum dieser Test überhaupt existiert. Daher ist es sinnvoll, eine sehr einfache, wiederholbare Vorlage zu haben: Ein Test – eine Fehlerursache; und im Test ist klar sichtbar, was wir eingegeben haben.

Die einfachste Lernvorlage für unsere heutigen Szenarien sieht so aus: Wir nehmen @WebMvcTest für einen bestimmten Controller, mocken den Service über @MockitoBean, rufen in jedem Test mvc.perform(...) auf, prüfen den Status und zusätzlich, dass der Service nicht angerührt wurde.

Wenn Sie das Rauschen durch „gültigen JSON“ reduzieren möchten, ist es in Ordnung, einen kleinen Helper zu definieren, der einen kanonisch korrekten Body zurückgibt. Hauptsache, die HTTP-Semantik wird nicht hinter einem mehrstöckigen DSL versteckt.

private static String validCreateArticleJson() {
    // Kanonischer “guter” JSON, um in Tests nur eine Fehlerursache zu ändern
    return """
        {"title":"T","summary":"S","body":"B","category":"JAVA"}
        """;
}

Der Test „für defekten JSON“ sollte nicht zu einem Test „für 10 verschiedene Dinge gleichzeitig“ werden. Er sendet einfach einen defekten Body.

@Test
void shouldReturn400_whenJsonIsBroken() throws Exception {
    mvc.perform(post("/api/editor/articles")
            .contentType(MediaType.APPLICATION_JSON)
            // Simuliere defekten JSON (Zeichenfolge abgeschnitten) – DTO wird nicht erstellt
            .content(validCreateArticleJson().substring(0, 10)))
        .andExpect(status().isBadRequest());

    // Fehler beim Lesen/Deserialisieren -> Service wird nicht aufgerufen
    then(service).shouldHaveNoInteractions();
}

Und ein Test auf Type Mismatch sollte überhaupt keinen Body mit sich führen, sonst erzeugen Sie eine zweite Fehlerquelle und verstehen nicht, warum genau 400 kommt.

@Test
void shouldReturn400_whenPathVariableHasWrongType() throws Exception {
    // Fehler bei der Konvertierung der Controller-Methodenargumente
    mvc.perform(get("/api/editor/articles/abc"))
        .andExpect(status().isBadRequest());

    then(service).shouldHaveNoInteractions();
}

Wenn ein Test „seltsam“ fehlschlägt und Sie nicht verstehen, warum – dann rettet andDo(print()) oft die Nerven. Das ist keine Assertion, aber ein hervorragender diagnostischer Hinweis.

import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;

@Test
void debugExample() throws Exception {
    mvc.perform(post("/api/editor/articles")
            .contentType(MediaType.APPLICATION_JSON)
            // Absichtlich defekten JSON senden, um zu sehen, wie Spring die Antwort formt
            .content("{"))
        .andDo(print()) // gibt Request/Response in der Konsole aus
        .andExpect(status().isBadRequest());
}

7. Was in Negativtests geprüft werden sollte

Negativtests können leicht „versalzen“ werden: Man beginnt innere Jackson-Fehlermeldungen, genaue Exception-Formulierungen, die Reihenfolge der Felder in der JSON-Antwort und andere Dinge zu prüfen, die sich mit Bibliotheksversionen oder Konfigurationen ändern. Ergebnis: Tests sind nur auf Ihrem Laptop grün und nur solange niemand die Abhängigkeiten aktualisiert. Daher ist es wichtig, bewusst den Grad der Strenge zu wählen: Wir müssen den Vertrag festhalten, aber die Testsuite nicht von zufälligen Details abhängig machen.

Für Fehler beim Lesen der Anfrage und Type Mismatch gibt es fast immer drei „Nutzungsebenen“.

Die grundlegendste Ebene: Status und fehlender Service-Aufruf. Sie ist universell und wird selten durch die Weiterentwicklung von Fehlermeldungen gebrochen. Dies ist der minimale Nachweis, dass der Fehler tatsächlich an der Web-Grenze und wirklich früh aufgetreten ist.

Die zweite Ebene: Prüfung des Fehlertyps über getResolvedException(). Dies ist nützlich, wenn Sie lernen, oder wenn innerhalb des Projekts tatsächlich die Gefahr besteht, die Ursachen von 400 zu verwechseln. In einer ausgereiften Testsuite wird dies manchmal zu einer unnötigen Bindung an MVC-Interna. Betrachten Sie es daher als Werkzeug: einsetzen, wenn es Sinn ergibt, nicht aus Gewohnheit.

Die dritte Ebene: Prüfung des Error-Payloads. Wenn das Projekt einen stabilen Error-Vertrag verwendet (in ContentHub ist das ApiProblem), können Sie grundlegende Felder prüfen, die als „API-Versprechen“ gelten: z. B. status und einen allgemeinen title. Aber für malformed JSON und conversion failures ist es wichtig, nicht zu erwarten, dass die Antwort wie eine „Validierung der DTO-Felder“ aussieht, weil das DTO nicht erstellt wurde. Das Feld violations kann z. B. leer sein oder fehlen – und das ist in Ordnung, wenn es so beabsichtigt ist.

Um nicht durcheinanderzukommen, kann man sich diesen „Rahmen“ merken:

Fehlerklasse Was sinnvoll zu prüfen ist Was besser nicht festgeschrieben werden sollte
Malformed JSON 400, Service nicht aufgerufen, (optional) HttpMessageNotReadableException genauer detail-Text von Jackson, „violations wie bei Validation“
JSON nicht auf DTO abbildbar 400, Service nicht aufgerufen konkrete Ursache MismatchedInputException im Text
Type mismatch 400, Service nicht aufgerufen, (optional) MethodArgumentTypeMismatchException Interpretation als „Ressource nicht gefunden“
Falscher Content-Type 415, Service nicht aufgerufen Details der Meldung zu unsupported media type

Und noch eine nützliche Gewohnheit: Ein Test – eine Ursache. Wenn Sie gleichzeitig malformed JSON und eine falsche Path Variable senden, testen Sie nicht „zwei Dinge“, sondern „irgendeines davon, aber wir wissen nicht welches“. Ein solcher Test kann aus einem der beiden Gründe grün werden – und genau das macht ihn gefährlich.

8. Typische Fehler beim Lesen der Anfrage

Bei Negativ-MVC-Tests liegt das Problem meist nicht in der Komplexität von Spring, sondern in schlichter menschlicher Bequemlichkeit: „Wird schon reichen“. Infolgedessen prüfen die Tests nicht die richtige Ebene, vermischen die Ursachen von 400 und erzeugen falsche Sicherheit. Im Folgenden einige typische Fallstricke speziell für malformed JSON, message conversion failures und type mismatch, die am häufigsten vorkommen und meist mehr Zeit fressen als die eigentliche Implementierung.

Fehler Nr. 1: Validation Failure und Fehler beim Body-Lesen verwechseln (und violations erwarten, wo kein DTO erstellt wurde).
Wenn die Anfrage nicht geparst oder nicht auf das DTO abgebildet werden konnte, wird Bean Validation nicht gestartet. Daher zu erwarten, dass die Antwort den gleichen Satz von Fehlern enthält wie bei @NotBlank, ist ein logischer Fehler. Entscheiden Sie im Test zunächst: Wurde ein DTO erstellt oder nicht? Wenn nein, prüfen Sie Status, fehlenden Service-Aufruf und bei Bedarf den Ausnahmetyp.

Fehler Nr. 2: Einen Test auf 400 schreiben und glauben, dass die Fehlerursache bereits bewiesen ist.
400 ist nur eine Antwortklasse für „fehlerhafte Anfrage“ und hat viele Ursachen. Ein einzelnes andExpect(status().isBadRequest()) ist oft zu schwach als Nachweis. Fügen Sie mindestens einen Marker hinzu: Service nicht aufgerufen, Prüfung des Ausnahmetyps oder Prüfung eines grundlegenden Feldes im Error-Payload (wenn der Vertrag stabil ist). Sonst erhalten Sie schnell einen grünen Test, der aus einem anderen Grund besteht.

Fehler Nr. 3: Content-Type nicht setzen und sich dann über 415 oder „seltsames“ Verhalten wundern.
@RequestBody erfordert fast immer einen ehrlichen Content-Type. In Tests ist das besonders wichtig, weil wir einen realen HTTP-Client simulieren. Wenn Sie JSON-Parsing testen, setzen Sie explizit application/json. Wenn Sie den falschen Media-Typ testen, setzen Sie den falschen und erwarten 415. Verlassen Sie sich nicht darauf, dass Spring es „schon erraten wird“.

Fehler Nr. 4: Für /api/editor/articles/abc 404 erwarten.
abc ist keine gültige ID. Das ist nicht „Ressource nicht gefunden“, sondern „ungültiges Format der Eingabedaten“. Semantisch ist das 400. Wenn Sie auf 404 prüfen, zwingen Sie den Controller und den Fehlerhandler, den Client anzulügen: Sie sagen dann „nicht gefunden“, obwohl sie eigentlich „konnten nicht lesen“ meinen.

Fehler Nr. 5: Service mocken und given(service...) in einem Test konfigurieren, in dem der Service nicht aufgerufen werden sollte.
Wenn der Fehler auf der Ebene der message conversion oder des type mismatch auftritt, sollte die Service-Logik nicht ausgeführt werden. Wenn Sie in einem solchen Test given(service.create(...)).willThrow(...) vorbereiten, schreiben Sie ein Szenario, das niemals eintritt. Viel nützlicher ist es, shouldHaveNoInteractions zu prüfen – das ist sowohl kürzer als auch ehrlicher.

1
Aufgabe
Spring Test, Level 12, Lektion 1
Gesperrt
Malformed JSON bei Erstellung einer Anzeige
Malformed JSON bei Erstellung einer Anzeige
1
Aufgabe
Spring Test, Level 12, Lektion 1
Gesperrt
Falscher Typ `id` im Editor-Endpoint
Falscher Typ `id` im Editor-Endpoint
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION