如何测试JSON路径是否不包含特定元素,或者如果该元素存在,则为null?

问题描述 投票:72回答:3

我一直在为简单的Spring Web应用程序编写一些简单的单元测试例程。当我在资源的getter方法上添加@JsonIgnore批注时,所得的json对象不包含相应的json元素。因此,当我的单元测试例程尝试测试它是否为null时(这是我的情况的预期行为,我不希望密码在json对象中可用),测试例程会遇到异常:

java.lang.AssertionError:JSON路径:$ .password没有值,例外:路径:$ ['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()。exists(),它得到了类似的异常,指出该路径不存在。我正在共享更多代码片段,以使整个情况更具可读性。

我正在测试的控制器方法看起来像这样:

@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: check that key exists but value may be null

就我而言,该字段也可能不存在。

记录下来,这些是我使用的测试软件包的版本:

    <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路径匹配器的文档后,找到了一个与最新版本的jayway.jasonpath一起使用的快速修复程序。

.andExpect(jsonPath("$.password").doesNotExist())

我一直在为简单的Spring Web应用程序编写一些简单的单元测试例程。当我在资源的getter方法上添加@JsonIgnore批注时,所得的json对象不会...

java unit-testing spring-mvc jsonpath mockmvc
3个回答
142
投票

我在较新的版本中遇到相同的问题。在我看来,dosNotExist()函数将验证密钥不在结果中:


4
投票

@@ JsonIgnore的行为符合预期,没有在json输出中生成密码,所以您怎么期望测试您明确从输出中排除的内容?


0
投票

[doesNotHaveJsonPath用于检查它是否不在json正文中

© www.soinside.com 2019 - 2024. All rights reserved.