Я писав кілька простих процедур модульного тестування для простого весняного веб-додатку. Коли я додаю анотацію @JsonIgnore для методу отримання ресурсу, отриманий об'єкт json не включає відповідний елемент json. Отже, коли моя підпрограма модульного тесту намагається перевірити, чи є це значення нульовим (що є очікуваною поведінкою для мого випадку, я не хочу, щоб пароль був доступний в об'єкті json), тестова підпрограма запускає виняток:
java.lang.AssertionError: Немає значення для шляху JSON: $ .password, виняток: Немає результатів для шляху: $ ['пароль']
Це метод модульного тестування, який я написав, тестуючи поле 'пароль' методом is (nullValue ()):
@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());
}
Я також спробував це за допомогою jsonPath (). Існує (), яке отримує подібне виняток, заявляючи, що шлях не існує. Я ділюсь ще кількома фрагментами коду, щоб вся ситуація стала читабельнішою.
Метод контролера, який я тестую, виглядає приблизно так:
@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);
}
}
Я використовую асемблер ресурсів hateos spring для перетворення сутності в об'єкти ресурсів, і це мій клас ресурсів:
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;
}
}
Я розумію, чому це отримує виняток, також певним чином, тест успішний, оскільки він не міг знайти поле пароля. Але що я хочу зробити, це запустити цей тест, щоб переконатися, що поле відсутнє, або якщо воно присутнє, воно містить нульове значення. Як я можу цього досягти?
У переповненні стека є подібний пост: Hamcrest з MockMvc: перевірте, чи існує ключ, але значення може бути нульовим
У моєму випадку поле може також не існувати.
Для запису, це версії тестових пакетів, які я використовую:
<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>
Заздалегідь спасибі.
[РЕДАКТУВАТИ] Якщо бути точнішим, скажімо, ви повинні написати тест для сутності, де ви знаєте, що деякі поля мають бути нульовими або порожніми, або навіть не повинні існувати, і ви насправді не проглядаєте код, щоб побачити якщо зверху властивості додано JsonIgnore. І ви хочете, щоб ваші тести пройшли, як я можу це зробити.
Будь ласка, не соромтеся сказати мені, що це зовсім не практично, але все одно було б приємно це знати.
[РЕДАКТУВАТИ] Наведений вище тест вдався за допомогою наступних старих залежностей json-path:
<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>
[EDIT] Знайдено швидке виправлення, яке працює з останньою версією jayway.jasonpath після прочитання документації збігового шляху json spring.
.andExpect(jsonPath("$.password").doesNotExist())
.doesNotExist()
було те, що я шукав.