当前位置: 首页 > 知识库问答 >
问题:

如何测试JSON路径是否不包含特定的元素,或者如果元素存在它是空的?

邹俊豪
2023-03-14

我一直在为一个简单的spring web应用程序编写一些简单的单元测试例程。当我在资源的getter方法上添加@JSONIgnore注释时,得到的json对象不包括相应的json元素。因此,当我的单元测试例程尝试测试这是否为空(这是我的情况的预期行为,我不希望密码在json对象中可用)时,测试例程运行到一个异常:

java.lang.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().exists()进行了尝试,它会得到类似的异常,指出路径不存在。我正在分享一些更多的代码片段,以便整个情况变得更易读。

我正在测试的controller方法如下所示:

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

我明白为什么这是得到一个异常,也在某种程度上,测试是成功的,它不能找到密码字段。但我想做的是,运行这个测试以确保字段不存在,或者如果存在,它包含空值。我怎样才能做到这一点呢?

在stack overflow:Hamcrest with mockmvc:check that key existant,但value可能为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>

提前道谢。

[EDIT]更准确地说,比方说,您必须为一个实体编写一个测试,在该实体中,您知道某些字段需要为null或空,或者甚至不应该存在,而您实际上并不检查代码,以查看是否在属性之上添加了JsonIgnore(一个JsonIgnore(一个JsonIgnore(一个JsonIgnore(一个JsonIgnore(一个JsonIgnore))。你想让你的测试通过,我怎么能这么做。

[EDIT]上面的测试成功使用了以下较旧的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]在阅读Spring的json路径匹配器文档后,找到了一个适用于最新版本的jayway.jasonPath的quickfix。

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

共有1个答案

白哲茂
2023-03-14

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

.andExpect(jsonPath("$.password").doesNotExist())
 类似资料:
  • 我已经将Selenium WebDriver添加到Powershell并创建WebDriver实例: 现在我要找到输入字段: 我发现了几个如何在C#中“测试元素是否存在”的例子: Selenium WebDriver-测试元素是否存在

  • 问题内容: 如何检查seleniumWeb元素是否包含特定的CSS类。 我有这个html li元素 如您所见,在class属性内部有一个活动类。 我的问题是我有这个元素,我想根据class属性是否具有其他“ active”值进行检查,这是比使用xpath更优雅的解决方案。 我怎样才能做到这一点? 问题答案: 鉴于您已经找到了您的元素,并且您想检查class属性内的某个类: 正如@aurelius正

  • 好的,我的情况如下: 在我测试的网站上,我测试的一部分包括一个表,用户可以在其中添加或删除行。我无法控制表是否是空的,所以我需要条件(IF)来探索两种场景: 1.桌子是空的;2.桌子不是空的。 我想到的只是检查表的第一行是否存在。如果有,做一些测试,然后继续,如果没有跳过表格,继续下一篇文章。 当然,我不能试着在第一行做一个cy.get,因为如果它找不到元素,它将无法通过测试,所以我尝试了以下方法

  • 我有这个ArrayList- ,一个整数被添加到移动[1]。然后将该数组添加到ArrayList中,然后重复该过程,这样我就有了一个“移动”列表。 我的问题是,我不确定如何在ArrayList(“树”)中找到仅在元素中包含特定值的数组(“移动”)——因为元素每次都是唯一的。 然后,我想制作一个所有匹配项的数组/列表。例如,一个数组,它包含与3的值相匹配的所有移动值。因此,我会留下一个数组/2D数组

  • 问题内容: 有没有一种方法可以测试元素是否存在?任何findElement方法都将以异常结尾,但这不是我想要的,因为它可能是一个元素不存在并且没关系,这不是测试失败,因此异常不能成为解决方案。 我发现了这篇文章:Seleniumc#Webdriver:等待元素出现,但这是针对C#的,我不是很擅长。谁能将代码翻译成Java?抱歉,我在Eclipse中进行了尝试,但我没有将其正确地插入Java代码中。