Wie kann ich testen, ob der JSON-Pfad kein bestimmtes Element enthält oder, wenn das Element vorhanden ist, null ist?
Schreibe ich einige einfache unit-Test-Routinen für eine einfache spring-web-Anwendung. Wenn ich @JsonIgnore Anmerkung auf einer getter-Methode auf einer Ressource, die daraus resultierende json-Objekt nicht enthalten ist die entsprechende json-element. Also, wenn meine unit-test-routine versucht, um zu testen, ob diese null ist (das ist das erwartete Verhalten für meinen Fall, ich möchte nicht, das ein Passwort zur Verfügung, die in json-Objekt), test-routine läuft in eine Ausnahme:
java.lang.AssertionError: Kein Wert für JSON-Pfad: $.Passwort, Ausnahme: Keine Ergebnisse für Pfad: $['password']
Dies ist der unit-test-Methode, die ich schrieb, Test-Feld 'Passwort' ist(nullValue()) Methode:
@Test
public void getUserThatExists() throws Exception {
User user = new User();
user.setId(1L);
user.setUsername("zobayer");
user.setPassword("123456");
when(userService.getUserById(1L)).thenReturn(user);
mockMvc.perform(get("/users/1"))
.andExpect(jsonPath("$.username", is(user.getUsername())))
.andExpect(jsonPath("$.password", is(nullValue())))
.andExpect(jsonPath("$.links[*].href", hasItem(endsWith("/users/1"))))
.andExpect(status().isOk())
.andDo(print());
}
Habe ich auch schon versucht es mit jsonPath().exists (), die bekommt ähnliche Ausnahme, die besagt, dass der Pfad nicht vorhanden ist. Ich bin teilen einige mehr code snippets, so dass die ganze situation immer mehr lesbar.
Die controller Methode, die ich am testen sieht wie folgt aus:
@RequestMapping(value="/users/{userId}", method= RequestMethod.GET)
public ResponseEntity<UserResource> getUser(@PathVariable Long userId) {
logger.info("Request arrived for getUser() with params {}", userId);
User user = userService.getUserById(userId);
if(user != null) {
UserResource userResource = new UserResourceAsm().toResource(user);
return new ResponseEntity<>(userResource, HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
Bin ich mit spring hateos Ressource assembler für die Umwandlung von entity resource-Objekte, und dies ist meine Ressource-Klasse:
public class UserResource extends ResourceSupport {
private Long userId;
private String username;
private String password;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@JsonIgnore
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Verstehe ich warum dies ist immer eine Ausnahme, auch in einer Weise, die der test erfolgreich ist, dass es nicht finden konnten, das Passwort-Feld. Aber was ich will zu tun ist, führen Sie diesen test, um sicherzustellen, dass das Feld ist nicht vorhanden, oder wenn vorhanden, enthält es den Wert null. Wie kann ich das erreichen?
Es gibt einen ähnlichen Beitrag im stack-overflow:
Hamcrest mit MockMvc: überprüfen Sie, ob der Schlüssel existiert, aber der Wert kann null sein
In meinem Fall, das Feld ist nicht existent, als gut.
Für die Aufnahme, dies sind die Versionen der test-Pakete, die ich benutze:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path-assert</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
Vielen Dank im Voraus.
[BEARBEITEN]
Um genauer zu sein, sagen, Sie schreiben einen test für ein Unternehmen, wo Sie wissen, einige der Felder müssen null oder leer ist oder nicht existiert, und Sie nicht wirklich durch den code gehen, um zu sehen, ob es eine JsonIgnore Hinzugefügt am oberen Rand der Eigenschaft. Und Sie möchten, dass Ihre tests zu übergeben, wie kann ich dies tun.
Fühlen Sie bitte sich frei, mir zu sagen, dass dies nicht praktikabel ist, aber wäre noch schön zu wissen.
[BEARBEITEN]
Der obige test erfolgreich, mit den folgenden älteren json-Pfad-Abhängigkeiten:
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>0.9.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path-assert</artifactId>
<version>0.9.1</version>
<scope>test</scope>
</dependency>
[BEARBEITEN] Finden Sie einen quickfix, der funktioniert mit der neuesten version von jayway.jasonpath nach dem Lesen der Dokumentation von spring json-Pfad matcher.
.andExpect(jsonPath("$.password").doesNotExist())
InformationsquelleAutor der Frage Zobayer Hasan | 2015-09-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich hatte das gleiche problem mit der neueren version. Es scheint mir, dass die doesNotExist () - Funktion stellen Sie sicher, dass der Schlüssel nicht in das Ergebnis:
InformationsquelleAutor der Antwort benezra444
@JsonIgnore verhält wie erwartet, nicht die Herstellung der password in die json-Ausgabe, wie konnte Sie erwarten, etwas zu testen, Sie sind ausdrücklich ausgenommen von der Ausgabe?
Die Zeile:
oder sogar ein test, der die Eigenschaft hat den Wert null:
entspricht einem json wie:
wo ist der wichtige Teil der linken Seite, ist die Existenz von "Eigentum":
Stattdessen @JsonIgnore ist nicht die Herstellung der Haus - /Wohnungseigentümer in der Ausgabe, daher können Sie nicht erwarten, dass es nicht in der test-noch in der Produktion.
Wenn Sie nicht möchten, dass die Eigenschaft in der Ausgabe, es ist in Ordnung, aber man kann nicht erwarten, dass es im test.
Wenn Sie möchten, dass es leer ist, in die Ausgabe (sowohl in der prod und test), die Sie möchten, erstellen Sie eine statische Mapper-Methode in der Mitte, die nicht durch den Wert der Eigenschaft auf das json-Objekt:
und dann deine Methode wäre:
Zu diesem Zeitpunkt, wenn Ihre Erwartungen für Mapper.mapPersonToRest zurück ein Benutzer mit einem null-Kennwort, Sie können schreiben Sie eine normal Unit-test auf diese Methode.
P. S. natürlich das Passwort ist crypted auf die DB, richtig? 😉
InformationsquelleAutor der Antwort Paolof76