如何测试JSON路径是否不包含特定元素,或者如果元素存在则为null? [英] How to test if JSON path does not include a specific element, or if the element is present it is null?

查看:334
本文介绍了如何测试JSON路径是否不包含特定元素,或者如果元素存在则为null?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have been writing some simple unit testing routines for a simple spring web application. When I add @JsonIgnore annotation on a getter method of a resource, the resulting json object does not include the corresponding json element. So when my unit test routine tries to test if this is null (which is the expected behavior for my case, I don't want the password to be available in json object), test routine runs into an exception:


java.lang.AssertionError:JSON路径没有值:$ .password,异常:路径没有结果:$ ['password']

java.lang.AssertionError: No value for JSON path: $.password, exception: No results for path: $['password']

这是我编写的单元测试方法,用is(nullValue())方法测试'password'字段:

This is the unit test method I wrote, testing the 'password' field with is(nullValue()) method:

@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()得到类似的东西异常声明该路径不存在。我正在分享更多的代码片段,以便整个情况变得更具可读性。

I have also tried it with jsonPath().exists() which gets similar exception stating that the path doesn't exist. I am sharing some more code snippets so that the whole situation becomes more readable.

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

The controller method I am testing looks something like this:

@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资源汇编程序将实体转换为资源对象,这是我的资源类:

I am using spring hateos resource assembler for converting entity to resource objects and this is my resource class:

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;
    }
}

我理解为什么会出现异常,也是一种方式,测试成功,它找不到密码字段。但我想要做的是,运行此测试以确保该字段不存在,或者如果存在,则它包含空值。我怎样才能实现这个目标?

I understand why this is getting an exception, also in a way, the test is successful that it could not find the password field. But what I want to do is, run this test to ensure that the field is not present, or if present, it contains null value. How can I achieve this?

堆栈溢出中有类似的帖子:

There is a similar post in stack overflow: Hamcrest with MockMvc: check that key exists but value may be null

在我的情况下,该字段也可能不存在。

In my case, the field may be non existent as well.

对于记录,这些是我正在使用的测试包的版本:

For the record, these are the versions of test packages I am using:

    <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。并且你希望你的测试通过,我该怎么做。

To be more precise, say, you have to write a test for an entity where you know some of the fields need to be null or empty or should not even exists, and you don't actually go through the code to see if there is a JsonIgnore added on top of the property. And you want your tests to pass, how can I do this.

请随时告诉我这根本不实用,但仍然很高兴知道。

Please feel free to tell me that this is not practical at all, but still would be nice to know.


以上测试成功与以下较旧的json路径依赖关系:

The above test succeeds with the following older json-path dependencies:

    <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的文档后,找到了一个适用于最新版jayway.jasonpath的quickfix json path matcher。

Found a quickfix that works with latest version of jayway.jasonpath after reading the documentation of spring's json path matcher.

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


推荐答案

我对新版本遇到了同样的问题。在我看来,doesNotExist()函数将验证该键不在结果中:

I had the same problem with the newer version. It looks to me that the doesNotExist() function will verify that the key is not in the result:

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

这篇关于如何测试JSON路径是否不包含特定元素,或者如果元素存在则为null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆