我一直在为一个简单的 Spring Web 应用程序编写一些简单的单元测试例程。当我在资源的 getter 方法上添加@JsonIgnore 注释时,生成的 json 对象不包含相应的 json 元素。因此,当我的单元测试例程试图测试这是否为 null (这是我的例子所期望的行为,我不希望密码在 json 对象中可用)时,测试例程会遇到一个异常:
AssertionError: 没有 JSON 路径的值: $. password,异常: 没有路径的结果: $[‘ password’]
这是我编写的单元测试方法,用 is (nullValue ())方法测试“ password”字段:
@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);
}
}
我使用 spring hateos 资源汇编程序将实体转换为资源对象,这是我的资源类:
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 with 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>
先谢谢你。
[编辑] 更准确地说,您必须为一个实体编写一个测试,在这个实体中,您知道一些字段需要为 null 或空,或者甚至不应该存在,并且您实际上不需要遍历代码来查看在属性顶部是否添加了 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>
[编辑]在阅读 Spring 的 json path matcher 文档后,找到了一个可以使用 jayway.jasonpath 最新版本的快速修复程序。
.andExpect(jsonPath("$.password").doesNotExist())