Verwenden Sie AssertJ, um die JSON-Antwort zu testen, wenn Sie die mit @RestController von Spring MVC erstellte REST-API-Antwort mit MockMVC testen.
Ein Mechanismus zum Testen von HTTP-Anforderungen und -Antworten an den Controller, ohne den von Spring bereitgestellten Server zu starten. Da der Server beim Ausführen des Tests nicht gestartet wird, besteht der Vorteil, dass die Testausführungsgeschwindigkeit erhöht wird. Sie können den Spring-Anwendungskontext mit @AutoConfigureMockMvc starten. Auf diese Weise können Sie DI so ausführen, als hätten Sie die gesamte Anwendung gestartet.
Referenzseite: [Testing the Web Layer](Class ContentResultMatchers)
Das Testen mit MockMVC + @ AutoConfigureMockMvc hat den Vorteil, dass die gesamte Anwendung mit hoher Geschwindigkeit getestet werden kann. Ich hatte das Gefühl, dass der Mechanismus zum Überprüfen des von RestController zurückgegebenen JSON schwach war. Es gibt auch eine Methode, um den JSON der Antwort mit dem erwarteten Ergebnis zu vergleichen, aber Sie müssen den JSON des erwarteten Ergebnisses als Zeichenfolge übergeben.
Referenzseite: Class ContentResultMatchers
Testen Sie beispielsweise einen RestContorller, der eine Buchliste wie folgt zurückgibt:
Antwortklasse
Book.java
@Data
public class Book {
private int id;
private String name;
private String author;
}
Books.java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Books {
private List<Book> books;
}
Controller-Klasse
BookController
@RestController
public class BookController {
//Serviceklasse, die eine Buchliste zurückgibt
private final BookService bookService;
@Autowired
public BookController(BookService bookService) {
this.bookService = bookService;
}
@GetMapping("books")
public Books get() {
//Buchliste mit Service abrufen und zurücksenden
return bookService.getBooks();
}
}
In der ContentResultMatchers-Klasse gibt es eine öffentliche ResultMatcher-json-Methode (String jsonContent) zum Überprüfen von JSON Es ist vorbereitet. Übergeben Sie bei Verwendung dieser json-Methode die erwartete Ergebnis-JSON-Zeichenfolge als Argument. Innerhalb der json-Methode wird die übergebene Zeichenfolge in ein JSON-Objekt konvertiert und dann mit der Antwort des zu testenden Programms verglichen.
BookControllerTest
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class BookControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void test() throws Exception {
String expectedJson = "{books:[...]}"; //Erstellen Sie JSON des erwarteten Ergebnisses als Zeichenfolge
mockMvc.perform(get("/books"))
.andExpect(status().isOk()) //Überprüfen Sie den Statuscode der Antwort
.andExpect(content().json(expectedJson)); //Überprüfen Sie den JSON der Antwort
}
}
Ich habe einen Test mit der json-Methode geschrieben, aber ich dachte wie folgt.
-Wenn es viele JSON-Elemente gibt, ist es schwierig, eine JSON-Zeichenfolge mit dem erwarteten Ergebnis zu erstellen. Da die IDE-Vervollständigung nicht mit Zeichenfolgen funktioniert, treten wahrscheinlich Tippfehler auf. ↓ -Es scheint, dass es weniger Fehler gibt, wenn Sie ein Java-Objekt erstellen und es mit Jackson in eine Zeichenfolge konvertieren. ↓ -Wenn Sie ein Java-Objekt erstellen, ist es nicht effizienter, die von MockMVC zurückgegebenen Werte in Java-Objekte zu konvertieren und zu vergleichen? Ist es nicht bequemer, AssertJ für den Vergleich zwischen Objekten zu verwenden, weil es mehr Matcher hat?
MockMVC bietet eine Methode, mit der der Antworttext als Zeichenfolge abgerufen werden kann. Verwenden Sie diese Methode. Konvertieren Sie die erfasste Zeichenfolge mit Jackson in ein Objekt und vergleichen Sie sie mit AssertJ mit dem erwarteten Ergebnis. Der Code sieht folgendermaßen aus:
BookControllerTest
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class BookControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void test() throws Exception {
String responseJsonString = mockMvc.perform(get("/books"))
.andExpect(status().isOk())
.andReturn().getResponse().getContentAsString(); //Ruft den Antworttext als Zeichenfolge ab
ObjectMapper objectMapper = new ObjectMapper();
//In Jackson in ein Java-Objekt konvertieren
Books responseJson = objectMapper.readValue(responseJsonString, Books.class);
//Erstellen Sie erwartete Ergebnisse mit Java-Objekten
Books expected = new Books(new ArrayList<>());
//Vergleich
assertThat(responseJson).isEqualTo(expected);
}
}
Ob es besser ist, die ursprünglich vorbereitete json-Methode zu verwenden, hängt vom Inhalt des JSON ab, der von der Ziel-API zurückgegeben wird, und ich denke, es gibt auch eine Präferenz. Ich hoffe, es ist hilfreich zu wissen, dass es eine solche Methode gibt.
Recommended Posts