Wie schreibt man Test für einen Controller?

RezaScript

Bekanntes Mitglied
Hallo,

in Spring Boot habe ich einen RestController, der so aussieht:

Java:
@PostMapping(value = "/save-quote")
public Map<String, Object> saveQuote(@RequestBody NewQuote data) {
    return newQuoteService.saveQuote(data);
}

data könnte zum Beispiel sein:
JSON:
{
    "vorname": "Max",
    "name": "Mustermann",
    "aussehen": {
        "groesse": 180,
        "gewicht": 70
        "haarfarbe": "blond"
    }
}

Der Service liefert dann folgendes:
JSON:
{
    "status": "ok"
}
ODER
JSON:
{
    "status": "bad",
    "errors": {
        "vorname": "kein Wert",
        "gewicht": "Zahl ist zu hoch",
    }
}

Wie kann ich hierzu einen Test schreiben?
 
Es hängt davon ab, was genau du testen möchtest.
Wenn du nur die Methode an sich testen möchtest, also nur der Signatur der Methode folgend, dann kannst du sie einfach aufrufen mit einer Instanz der NewQuota Klasse und eine Expectation auf die zurückkommende Map machen.
Bei allem weiteren würdest du ja "nur" zusätzlich testen, ob Spring Web richtig funktioniert und die Daten richtig marshalled und unmarshalled.
Das kann sinnvoll sein, wenn du z.B. deine Beans im Gesamtkontext der Anwendung als "Configuration Test" siehst und testen möchtest.
 
Also so habe ich es zumindest mal so probiert:

Java:
@SpringBootTest
@AutoConfigureMockMvc
class NewQuoteControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    void saveQuote() throws Exception {

        this.mvc.perform(
                post("/save-quote").contentType(MediaType.APPLICATION_JSON).content("""
                {
                    "name": "Mustermann",
                    "aussehen": {
                        "groesse": 180,
                        "gewicht": 70
                        "haarfarbe": "blond"
                    }
                }
                """
                ))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(status().isOk())
                .andExpect(content().json("{ \"status\": \"ok\"}"));
    }
}

Das scheint sehr gut zu funktionieren.

Das ist mein erster Test, den ich bis jetzt geschrieben habe und um ehrlich zu sein, verstehe ich den Sinn und Zweck des ganzen nicht. Was soll jetzt hier der Unterschied zwischen dieses Scripts und ein Request mit Postman sein? Mit Postman muss ich nicht einmal etwas coden.
 
Ich interpretiere deine Frage mal so:
"""
Warum sollte ich einen automatisierten Test für meine HTTP Schnittstellen im Service haben, die ich automatisiert während meines CI Builds ausführen kann, um festzustellen, dass meine Änderungen keine Fehler enthalten, wenn ich das ganze stattdessen nach einem Deployment/Start der Anwendung händisch per Postman UI ausführen könnte?
"""
Ich nehme mal an, dass du deine Postman Tests selbst auch nicht automatisiert via z.B. newman ausführen lässt.
Und selbst wenn du z.B. newman verwenden würdest, um deine Postman collection auszuführen, müsstest du dafür ja immer noch deine Anwendung zumindest mal deployen bzw. starten, um die Tests dagegen ausführen zu können.
Das musst du hingegen nicht (bzw. nicht in dem Maße) mit einem SpringBootTest.
 
Was soll jetzt hier der Unterschied zwischen dieses Scripts und ein Request mit Postman sein?

Der Vorteil von automatisierten und im Projekt befindlichen Tests ist immer das sie automatisch im Projekt sind. Jeder Test fuer den du einen Extra-Schritt brauchst ist potenzielles "Oh, da habe ich darauf vergessen" oder noch besser "Davon wusste ich nichts". Alles immer und automatisiert direkt im Projekt zu machen ist immer die beste Loesung.
 

Zurück
Oben