Unit Tests für eine Spring MVC REST API schreiben:Daten schreiben
In den vorherigen Teilen meines Spring MVC Test-Tutorials wurde beschrieben, wie Sie Komponententests für eine Spring MVC-REST-API schreiben können, wenn das zu testende System die Informationen eines einzelnen Elements oder eine Liste zurückgibt. Mit anderen Worten, jetzt wissen wir, wie wir Komponententests für Spring MVC-Controller schreiben können, die Daten als JSON zurückgeben.
Es ist Zeit, den nächsten Schritt zu tun. Dieser Blogbeitrag beschreibt, wie wir Unit-Tests für einen Spring-MVC-REST-API-Endpunkt schreiben können, der Daten aus dem Anfragetext liest, gültige Daten in eine Datenbank einfügt und Daten als JSON zurückgibt.
Nachdem wir diesen Blogbeitrag fertiggestellt haben, werden wir:
- Wissen Sie, wie wir
POST
senden können Anfragen an das zu testende System und konfigurieren Sie den Anfragetext der HTTP-Anfrage. - Verstehen, wie wir sicherstellen können, dass das zu testende System wie erwartet funktioniert, wenn die Validierung fehlschlägt.
- Wissen, wie wir sicherstellen können, dass das zu testende System wie erwartet funktioniert, wenn die Validierung erfolgreich ist.
Fangen wir an.
Einführung in das zu testende System
Wir müssen Komponententests für eine Controller-Methode schreiben, die POST
verarbeitet Anfragen werden an den Pfad gesendet:'/todo-item'. Der Vertrag dieses API-Endpunkts wird im Folgenden beschrieben:
- Die Validierungsregeln müssen mithilfe der Jakarta Bean Validation API angegeben werden.
- Wenn die Validierung fehlschlägt, gibt das getestete System den HTTP-Statuscode 400 zurück.
- Wenn die Validierung fehlschlägt, gibt das getestete System ein JSON-Dokument zurück, das die in den Eingabedaten gefundenen Validierungsfehler beschreibt.
- Wenn ein neues Aufgabenelement erfolgreich erstellt wurde, gibt das zu testende System den HTTP-Statuscode 201 zurück.
- Wenn ein neues Todo-Element erfolgreich erstellt wurde, gibt das zu testende System ein JSON-Dokument zurück, das die Informationen des erstellten Todo-Elements enthält.
Die folgenden Beispiele veranschaulichen die JSON-Dokumente, die an den Client zurückgesendet werden:
Beispiel 1:Der Client hat versucht, ein neues Aufgabenelement ohne Titel zu erstellen
{ "fieldErrors":[ { "field":"title", "errorCode":"NotBlank" } ] }
Beispiel 2:Ein neues Aufgabenelement wurde erfolgreich erstellt
{ "id":1, "description":"This is just an example", "tags":[], "title":"Create a new todo item", "status":"OPEN" }
Die getestete Controller-Methode heißt create()
. Es speichert einfach ein neues Todo-Element in der Datenbank und gibt die Informationen des erstellten Todo-Elements zurück. Der Quellcode der getesteten Controller-Methode sieht wie folgt aus:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; @RestController @RequestMapping("/todo-item") public class TodoItemCrudController { private final TodoItemCrudService service; @Autowired public TodoItemCrudController(TodoItemCrudService service) { this.service = service; } @PostMapping @ResponseStatus(HttpStatus.CREATED) public TodoItemDTO create(@RequestBody @Valid CreateTodoItemDTO input) { return service.create(input); } }
Die CreateTodoItemDTO
Klasse enthält die Informationen des erstellten ToDo-Elements. Außerdem werden die Validierungsregeln deklariert, die zur Validierung dieser Informationen verwendet werden. Sein Quellcode sieht wie folgt aus:
import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; public class CreateTodoItemDTO { @Size(max = 1000) private String description; @NotBlank @Size(max = 100) private String title; //Getters and setters are omitted }
Die TodoItemDTO
Klasse enthält die Informationen des erstellten ToDo-Elements. Sein Quellcode sieht wie folgt aus:
import java.util.List; public class TodoItemDTO { private Long id; private String description; private List<TagDTO> tags; private String title; private TodoItemStatus status; //Getters and setters are omitted }
Die TagDTO
Klasse enthält die Informationen eines einzelnen Tags. Sein Quellcode sieht wie folgt aus:
public class TagDTO { private Long id; private String name; //Getters and setters are omitted }
Die TodoItemStatus
enum gibt die möglichen Status eines Aufgabeneintrags an. Sein Quellcode sieht wie folgt aus:
public enum TodoItemStatus { OPEN, IN_PROGRESS, DONE }
Als Nächstes lernen wir, wie wir Assertionen für die vom zu testenden System zurückgegebene Antwort schreiben können.
Schreiben von Zusicherungen für die Antwort, die vom zu testenden System zurückgegeben wird
Bevor wir Komponententests für einen Spring MVC-Controller schreiben können, der Daten in der Datenbank speichert und Daten als JSON zurückgibt, müssen wir lernen, wie wir Zusicherungen für die vom zu testenden System zurückgegebene HTTP-Antwort schreiben können. Wenn wir Zusicherungen für die vom getesteten Spring MVC-Controller zurückgegebene HTTP-Antwort schreiben möchten, müssen wir diese static
verwenden Methoden der MockMvcResultMatchers
Klasse:
- Der
status()
-Methode gibt einStatusResultMatchers
zurück Objekt, das es uns erlaubt, Assertionen für den zurückgegebenen HTTP-Status zu schreiben. - Die
content()
Methode gibt einenContentResultMatchers
zurück -Objekt, das es uns ermöglicht, Zusicherungen für den Inhalt der zurückgegebenen HTTP-Antwort zu schreiben. - Die
jsonPath()
Methode gibt einenJsonPathResultMatchers
zurück -Objekt, das es uns ermöglicht, Assertionen für den Text der zurückgegebenen HTTP-Antwort zu schreiben, indem wir JsonPath-Ausdrücke und Hamcrest-Matcher verwenden.
Da wir Behauptungen mithilfe von JsonPath-Ausdrücken und Hamcrest-Matchern schreiben, müssen wir sicherstellen, dass der json-path
und hamcrest-library
Abhängigkeiten werden aus dem Klassenpfad gefunden. Wenn wir die Maven- und Spring Boot-Abhängigkeitsverwaltung verwenden, können wir diese Abhängigkeiten deklarieren, indem wir das folgende XML-Snippet zum dependencies
hinzufügen Abschnitt unserer POM-Datei:
<dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-library</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.jayway.jsonpath</groupId> <artifactId>json-path</artifactId> <scope>test</scope> </dependency>
Lassen Sie uns weitermachen und herausfinden, wie wir eine Request-Builder-Methode schreiben können, die POST
sendet Anfragen an das zu testende System.
Schreiben einer neuen Request Builder-Methode
Da wir doppelten Code aus unserer Testklasse entfernen möchten, müssen wir HTTP-Anforderungen erstellen und an das zu testende System senden, indem wir eine sogenannte Request-Builder-Klasse verwenden. Mit anderen Worten, bevor wir Komponententests für das zu testende System schreiben können, müssen wir in eine Request-Builder-Methode schreiben, die HTTP-Anforderungen erstellt und an das zu testende System sendet. Wir können diese Request-Builder-Methode schreiben, indem wir diesen Schritten folgen:
- Fügen Sie einen
private
hinzu undstatic
Methode namensconvertObjectToJsonBytes()
unsere Request-Builder-Klasse und stellen Sie sicher, dass diese Methode ein Byte-Array zurückgibt. - Stellen Sie sicher, dass der
convertObjectToJsonBytes()
Methode nimmt einenObject
object als Methodenparameter und konvertiert dieses Objekt in ein Byte-Array, das ein JSON-Dokument enthält. - Fügen Sie eine neue Methode namens
create()
hinzu zu unserer Request-Builder-Klasse. Stellen Sie sicher, dass diese Methode einenCreateTodoItemDTO
akzeptiert Objekt als Methodenparameter und gibt einResultActions
zurück Objekt. - Senden Sie einen
POST
Anfrage an den Pfad:'/todo-item' durch Aufrufen desperform()
Methode desMockMvc
Klasse. Denken Sie daran, die Informationen des erstellten Todo-Elements in ein JSON-Dokument zu konvertieren und diese Informationen zum Hauptteil der HTTP-Anforderung hinzuzufügen. - Gib den
ResultActions
zurück Objekt, das vonperform()
zurückgegeben wird Methode.
Nachdem wir unsere Request-Builder-Methode geschrieben haben, sieht der Quellcode unserer Request-Builder-Klasse wie folgt aus:
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import java.io.IOException; import static net.petrikainulainen.springmvctest.junit5.web.WebTestConfig.objectMapper; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; class TodoItemRequestBuilder { private final MockMvc mockMvc; TodoItemRequestBuilder(MockMvc mockMvc) { this.mockMvc = mockMvc; } ResultActions create(CreateTodoItemDTO input) throws Exception { return mockMvc.perform(post("/todo-item") .contentType(MediaType.APPLICATION_JSON) .content(convertObjectToJsonBytes(input)) ); } private static byte[] convertObjectToJsonBytes(Object object) throws IOException { ObjectMapper mapper = objectMapper(); return mapper.writeValueAsBytes(object); } }
Als Nächstes lernen wir, Unit-Tests für das zu testende System zu schreiben.
Einheitentests für das zu testende System schreiben
Wenn wir Unit-Tests für das zu testende System schreiben wollen, müssen wir diese Schritte befolgen:
Zuerst , müssen wir unserer Testklasse die erforderliche Klassenhierarchie hinzufügen. Da wir Komponententests schreiben, können wir diese Klassenhierarchie folgendermaßen erstellen:
- Fügen Sie eine innere Klasse namens
Create
hinzu zu unserer Testklasse. Diese innere Klasse enthält die Testmethoden, die sicherstellen, dass das zu testende System wie erwartet funktioniert. - Fügen Sie eine innere Klasse namens
WhenInvalidInformationIsProvided
hinzu zumCreate
Klasse. Diese innere Klasse enthält die Testmethoden, die sicherstellen, dass das zu testende System wie erwartet funktioniert, wenn die Validierung fehlschlägt. - Fügen Sie eine innere Klasse namens
WhenFieldValuesAreEmptyStrings
hinzu zumWhenInvalidInformationIsProvided
Klasse. Diese innere Klasse enthält die Testmethoden, die sicherstellen, dass das zu testende System wie erwartet funktioniert, wenn dertitle
unddescription
des erstellten Aufgabeneintrags sind leere Zeichenfolgen. - Fügen Sie eine innere Klasse namens
WhenValidInformationIsProvided
hinzu zumCreate
Klasse. Diese innere Klasse enthält die Testmethoden, die sicherstellen, dass das zu testende System bei erfolgreicher Validierung wie erwartet funktioniert.
Nachdem wir unserer Testklasse die erforderliche Klassenhierarchie hinzugefügt haben, sieht ihr Quellcode wie folgt aus:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static net.petrikainulainen.springmvctest.junit5.web.WebTestConfig.*; import static org.mockito.Mockito.mock; class TodoItemCrudControllerTest { private TodoItemRequestBuilder requestBuilder; private TodoItemCrudService service; @BeforeEach void configureSystemUnderTest() { service = mock(TodoItemCrudService.class); TodoItemCrudController testedController = new TodoItemCrudController(service); MockMvc mockMvc = MockMvcBuilders.standaloneSetup(testedController) .setControllerAdvice(new TodoItemErrorHandler()) .setMessageConverters(objectMapperHttpMessageConverter()) .build(); requestBuilder = new TodoItemRequestBuilder(mockMvc); } @Nested @DisplayName("Create a new todo item") class Create { @Nested @DisplayName("When the information of the created todo item isn't valid") class WhenInvalidInformationIsProvided { @Nested @DisplayName("When the field values are empty strings") class WhenFieldValuesAreEmptyStrings { } } @Nested @DisplayName("When the information of the created todo item is valid") class WhenValidInformationIsProvided { } } }
Zweite , müssen wir einen private input
hinzufügen Feld zum Create
Klasse. Dieses Feld enthält einen Verweis auf den CreateTodoItemDTO
Objekt, das die Informationen des erstellten Aufgabeneintrags enthält.
Nachdem wir dieses Feld zum Create
hinzugefügt haben Klasse sieht der Quellcode unserer Testklasse wie folgt aus:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static net.petrikainulainen.springmvctest.junit5.web.WebTestConfig.*; import static org.mockito.Mockito.mock; class TodoItemCrudControllerTest { private TodoItemRequestBuilder requestBuilder; private TodoItemCrudService service; @BeforeEach void configureSystemUnderTest() { service = mock(TodoItemCrudService.class); TodoItemCrudController testedController = new TodoItemCrudController(service); MockMvc mockMvc = MockMvcBuilders.standaloneSetup(testedController) .setControllerAdvice(new TodoItemErrorHandler()) .setMessageConverters(objectMapperHttpMessageConverter()) .build(); requestBuilder = new TodoItemRequestBuilder(mockMvc); } @Nested @DisplayName("Create a new todo item") class Create { private CreateTodoItemDTO input; @Nested @DisplayName("When the information of the created todo item isn't valid") class WhenInvalidInformationIsProvided { @Nested @DisplayName("When the field values are empty strings") class WhenFieldValuesAreEmptyStrings { } } @Nested @DisplayName("When the information of the created todo item is valid") class WhenValidInformationIsProvided { } } }
Dritter müssen wir sicherstellen, dass das zu testende System wie erwartet funktioniert, wenn wir versuchen, ein neues Todo-Element zu erstellen, das einen leeren title
hat und description
. Wir können die erforderlichen Testmethoden schreiben, indem wir diesen Schritten folgen:
- Fügen Sie die erforderlichen Konstanten zu
WhenFieldValuesAreEmptyStrings
hinzu Klasse. - Fügen Sie dem
WhenFieldValuesAreEmptyStrings
eine neue Einrichtungsmethode hinzu -Klasse und stellen Sie sicher, dass sie ausgeführt wird, bevor eine Testmethode ausgeführt wird. Wenn wir diese Methode implementieren, müssen wir einen neuenCreateTodoItemDTO
erstellen Objekt, das einen leerentitle
hat unddescription
, und speichern Sie das erstellte Objekt iminput
Feld. - Stellen Sie sicher, dass das zu testende System den HTTP-Statuscode 400 zurückgibt.
- Vergewissern Sie sich, dass das zu testende System Validierungsfehler als JSON zurückgibt.
- Stellen Sie sicher, dass das zu testende System einen Validierungsfehler zurückgibt.
- Vergewissern Sie sich, dass das zu testende System einen Validierungsfehler zu einem leeren Titel zurückgibt.
- Stellen Sie sicher, dass das zu testende System kein neues Aufgabenelement erstellt.
Nachdem wir die erforderlichen Testmethoden geschrieben haben, sieht der Quellcode unserer Testklasse wie folgt aus:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static net.petrikainulainen.springmvctest.junit5.web.WebTestConfig.*; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.hasSize; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; class TodoItemCrudControllerTest { private TodoItemRequestBuilder requestBuilder; private TodoItemCrudService service; @BeforeEach void configureSystemUnderTest() { service = mock(TodoItemCrudService.class); TodoItemCrudController testedController = new TodoItemCrudController(service); MockMvc mockMvc = MockMvcBuilders.standaloneSetup(testedController) .setControllerAdvice(new TodoItemErrorHandler()) .setMessageConverters(objectMapperHttpMessageConverter()) .build(); requestBuilder = new TodoItemRequestBuilder(mockMvc); } @Nested @DisplayName("Create a new todo item") class Create { private CreateTodoItemDTO input; @Nested @DisplayName("When the information of the created todo item isn't valid") class WhenInvalidInformationIsProvided { @Nested @DisplayName("When the field values are empty strings") class WhenFieldValuesAreEmptyStrings { private static final String VALIDATION_ERROR_EMPTY_VALUE = "NotBlank"; @BeforeEach void createInputWithEmptyFieldValues() { input = new CreateTodoItemDTO(); input.setDescription(""); input.setTitle(""); } @Test @DisplayName("Should return the HTTP status code bad request (400)") void shouldReturnHttpStatusCodeBadRequest() throws Exception { requestBuilder.create(input) .andExpect(status().isBadRequest()); } @Test @DisplayName("Should return validation errors as JSON") void shouldReturnValidationErrorsAsJson() throws Exception { requestBuilder.create(input) .andExpect( content().contentType(MediaType.APPLICATION_JSON) ); } @Test @DisplayName("Should return one validation error") void shouldReturnOneValidationError() throws Exception { requestBuilder.create(input) .andExpect(jsonPath("$.fieldErrors", hasSize(1))); } @Test @DisplayName("Should return a validation error about empty title") void shouldReturnValidationErrorAboutEmptyTitle() throws Exception { requestBuilder.create(input) .andExpect(jsonPath( "$.fieldErrors[?(@.field == 'title')].errorCode", contains(VALIDATION_ERROR_EMPTY_VALUE) )); } @Test @DisplayName("Shouldn't create a new todo item") void shouldNotCreateNewTodoItem() throws Exception { requestBuilder.create(input); verify(service, never()).create(any()); } } } //The other inner class is omitted } }
Vierter müssen wir sicherstellen, dass das zu testende System wie erwartet funktioniert, wenn die Validierung erfolgreich ist. Wir können die erforderlichen Testmethoden schreiben, indem wir diesen Schritten folgen:
- Fügen Sie die erforderlichen Konstanten zu
WhenValidInformationIsProvided
hinzu Klasse. - Fügen Sie dem
WhenValidInformationIsProvided
eine neue Einrichtungsmethode hinzu -Klasse und stellen Sie sicher, dass sie ausgeführt wird, bevor eine Testmethode ausgeführt wird. Wenn wir diese Methode implementieren, müssen wir:- Erstellen Sie einen neuen
CreateTodoItemDTO
Objekt mit gültigemtitle
unddescription
. Nachdem wir dieses Objekt erstellt haben, müssen wir es iminput
speichern Feld. - Stellen Sie sicher, dass der
create()
Methode desTodoItemCrudService
Die Klasse gibt die Informationen des erstellten ToDo-Elements zurück.
- Erstellen Sie einen neuen
- Stellen Sie sicher, dass das zu testende System den HTTP-Statuscode 201 zurückgibt.
- Vergewissern Sie sich, dass das zu testende System die Informationen des erstellten Todo-Elements als JSON zurückgibt.
- Stellen Sie sicher, dass das zu testende System die Informationen des erstellten Todo-Elements zurückgibt.
- Vergewissern Sie sich, dass das zu testende System ein neues Aufgabenelement mit der richtigen Beschreibung erstellt.
- Stellen Sie sicher, dass das zu testende System ein neues Aufgabenelement mit dem richtigen Titel erstellt.
Nachdem wir die erforderlichen Testmethoden geschrieben haben, sieht der Quellcode unserer Testklasse wie folgt aus:
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import java.util.ArrayList; import static info.solidsoft.mockito.java8.AssertionMatcher.assertArg; import static net.petrikainulainen.springmvctest.junit5.web.WebTestConfig.*; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; class TodoItemCrudControllerTest { private TodoItemRequestBuilder requestBuilder; private TodoItemCrudService service; @BeforeEach void configureSystemUnderTest() { service = mock(TodoItemCrudService.class); TodoItemCrudController testedController = new TodoItemCrudController(service); MockMvc mockMvc = MockMvcBuilders.standaloneSetup(testedController) .setControllerAdvice(new TodoItemErrorHandler()) .setMessageConverters(objectMapperHttpMessageConverter()) .build(); requestBuilder = new TodoItemRequestBuilder(mockMvc); } @Nested @DisplayName("Create a new todo item") class Create { private CreateTodoItemDTO input; //The other inner class is omitted @Nested @DisplayName("When the information of the created todo item is valid") class WhenValidInformationIsProvided { private static final int MAX_LENGTH_DESCRIPTION = 1000; private static final int MAX_LENGTH_TITLE = 100; private static final String DESCRIPTION = WebTestUtil .createStringWithLength(MAX_LENGTH_DESCRIPTION); private static final Long ID = 1L; private static final String TITLE = WebTestUtil .createStringWithLength(MAX_LENGTH_TITLE); @BeforeEach void configureSystemUnderTest() { input = createInputWithValidInformation(); returnCreatedTodoItem(); } private CreateTodoItemDTO createInputWithValidInformation() { CreateTodoItemDTO input = new CreateTodoItemDTO(); input.setDescription(DESCRIPTION); input.setTitle(TITLE); return input; } private void returnCreatedTodoItem() { TodoItemDTO created = new TodoItemDTO(); created.setId(ID); created.setDescription(DESCRIPTION); created.setStatus(TodoItemStatus.OPEN); created.setTags(new ArrayList<>()); created.setTitle(TITLE); given(service.create(any())).willReturn(created); } @Test @DisplayName("Should return the HTTP status status code created (201)") void shouldReturnHttpStatusCodeCreated() throws Exception { requestBuilder.create(input) .andExpect(status().isCreated()); } @Test @DisplayName("Should return the information of the created todo item as JSON") void shouldReturnInformationOfCreatedTodoItemAsJSON() throws Exception { requestBuilder.create(input) .andExpect(content().contentType(MediaType.APPLICATION_JSON)); } @Test @DisplayName("Should return the information of the created todo item") void shouldReturnInformationOfCreatedTodoItem() throws Exception { requestBuilder.create(input) .andExpect(jsonPath("$.id", equalTo(ID.intValue()))) .andExpect(jsonPath("$.description", equalTo(DESCRIPTION))) .andExpect(jsonPath("$.status", equalTo(TodoItemStatus.OPEN.name()) )) .andExpect(jsonPath("$.tags", hasSize(0))) .andExpect(jsonPath("$.title", equalTo(TITLE))); } @Test @DisplayName("Should create a new todo item with the correct description") void shouldCreateNewTodoItemWithCorrectDescription() throws Exception { requestBuilder.create(input); verify(service, times(1)).create(assertArg( created -> assertThat(created.getDescription()) .isEqualTo(DESCRIPTION) )); } @Test @DisplayName("Should create a new todo item with the correct title") void shouldCreateNewTodoItemWithCorrectTitle() throws Exception { requestBuilder.create(input); verify(service, times(1)).create(assertArg( created -> assertThat(created.getTitle()) .isEqualTo(TITLE) )); } } } }
Wir können jetzt Komponententests für einen Spring MVC REST API-Endpunkt schreiben, der Daten in die Datenbank einfügt und Daten als JSON zurückgibt. Fassen wir zusammen, was wir aus diesem Blogbeitrag gelernt haben.
Zusammenfassung
Dieser Blogbeitrag hat uns vier Dinge gelehrt:
- Wenn wir Zusicherungen für den zurückgegebenen HTTP-Status schreiben wollen, müssen wir den
status()
aufrufen Methode desMockMvcResultMatchers
Klasse. - Wenn wir Zusicherungen für den Inhalt der zurückgegebenen HTTP-Antwort schreiben wollen, müssen wir den
content()
aufrufen Methode desMockMvcResultMatchers
Klasse. - Wenn wir Zusicherungen für den Hauptteil der zurückgegebenen HTTP-Antwort schreiben möchten, indem wir JsonPath-Ausdrücke und Hamcrest-Matcher verwenden, müssen wir den
jsonPath()
aufrufen Methode desMockMvcResultMatchers
Klasse. - Wenn wir Zusicherungen für den Hauptteil der zurückgegebenen HTTP-Antwort schreiben möchten, indem wir JsonPath-Ausdrücke und Hamcrest-Matcher verwenden, müssen wir sicherstellen, dass der
json-path
undhamcrest-library
Abhängigkeiten werden aus dem Klassenpfad gefunden