Ich habe einige einfache Unit-Test-Routinen für eine einfache Spring-Webanwendung geschrieben. Wenn ich eine @ JsonIgnore-Annotation zu einer Getter-Methode einer Ressource hinzufüge, enthält das resultierende JSON-Objekt nicht das entsprechende JSON-Element. Wenn meine Unit-Test-Routine versucht zu testen, ob dies null ist (was das erwartete Verhalten für meinen Fall ist, ich möchte nicht, dass das Kennwort im JSON-Objekt verfügbar ist), tritt bei der Testroutine eine Ausnahme auf:
java.lang.AssertionError: Kein Wert für JSON-Pfad: $ .password, Ausnahme: Keine Ergebnisse für Pfad: $ ['password']
Dies ist die Unit-Test-Methode, die ich geschrieben habe. Dabei wurde das Feld 'password' mit der Methode is (nullValue ()) getestet:
@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());
}
Ich habe es auch mit jsonPath () versucht. Exists (), das eine ähnliche Ausnahme erhält, die besagt, dass der Pfad nicht existiert. Ich teile einige weitere Codefragmente, damit die gesamte Situation besser lesbar wird.
Die Controller-Methode, die ich teste, sieht ungefähr so 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);
}
}
Ich verwende Spring Hateos Resource Assembler zum Konvertieren von Entitäten in Ressourcenobjekte. Dies ist meine Ressourcenklasse:
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;
}
}
Ich verstehe, warum dies eine Ausnahme bekommt, auch in gewisser Weise ist der Test erfolgreich, dass es das Passwortfeld nicht finden konnte. Ich möchte diesen Test jedoch ausführen, um sicherzustellen, dass das Feld nicht vorhanden ist oder, falls vorhanden, einen Nullwert enthält. Wie kann ich das erreichen?
Es gibt einen ähnlichen Beitrag im Stapelüberlauf: Hamcrest mit MockMvc: Überprüfen Sie, ob der Schlüssel vorhanden ist, der Wert jedoch möglicherweise null ist
In meinem Fall ist das Feld möglicherweise auch nicht vorhanden.
Dies sind die Versionen der Testpakete, die ich verwende:
<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>
Danke im Voraus.
[BEARBEITEN] Um genauer zu sein, müssen Sie beispielsweise einen Test für eine Entität schreiben, bei der Sie wissen, dass einige der Felder null oder leer sein müssen oder gar nicht existieren sollten, und Sie den Code nicht durchgehen, um zu sehen Wenn über der Eigenschaft ein JsonIgnore hinzugefügt wurde. Und Sie möchten, dass Ihre Tests bestanden werden. Wie kann ich das tun?
Bitte zögern Sie nicht, mir zu sagen, dass dies überhaupt nicht praktikabel ist, aber dennoch schön zu wissen wäre.
[EDIT] Der obige Test ist mit den folgenden älteren JSON-Pfad-Abhängigkeiten erfolgreich:
<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] Es wurde ein Quickfix gefunden, der mit der neuesten Version von jayway.jasonpath funktioniert, nachdem die Dokumentation des json path matcher von spring gelesen wurde.
.andExpect(jsonPath("$.password").doesNotExist())
.doesNotExist()
war was ich suche.