【问题标题】:count members with jsonpath?用 jsonpath 计算成员?
【发布时间】:2012-11-24 14:00:01
【问题描述】:

是否可以使用 JsonPath 统计成员数?

使用spring mvc test 我正在测试一个生成的控制器

{"foo": "oof", "bar": "rab"}

standaloneSetup(new FooController(fooService)).build()
            .perform(get("/something").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
            .andExpect(jsonPath("$.foo").value("oof"))
            .andExpect(jsonPath("$.bar").value("rab"));

我想确保生成的 json 中没有其他成员。希望通过使用 jsonPath 计算它们。可能吗?也欢迎其他解决方案。

【问题讨论】:

    标签: java spring testing jsonpath spring-test-mvc


    【解决方案1】:

    我们可以像size()length() 一样使用JsonPath functions,像这样:

    @Test
    public void givenJson_whenGetLengthWithJsonPath_thenGetLength() {
        String jsonString = "{'username':'jhon.user','email':'jhon@company.com','age':'28'}";
    
        int length = JsonPath
            .parse(jsonString)
            .read("$.length()");
    
        assertThat(length).isEqualTo(3);
    }
    

    或者直接解析成net.minidev.json.JSONObject,得到大小:

    @Test
    public void givenJson_whenParseObject_thenGetSize() {
        String jsonString = "{'username':'jhon.user','email':'jhon@company.com','age':'28'}";
    
        JSONObject jsonObject = (JSONObject) JSONValue.parse(jsonString);
    
        assertThat(jsonObject)
            .size()
            .isEqualTo(3);
    }
    

    确实,第二种方法看起来比第一种方法执行得更好。我进行了 JMH 性能测试,得到以下结果:

    | Benchmark                                       | Mode  | Cnt | Score       | Error        | Units |
    |-------------------------------------------------|-------|-----|-------------|--------------|-------|
    | JsonPathBenchmark.benchmarkJSONObjectParse      | thrpt | 5   | 3241471.044 | ±1718855.506 | ops/s |
    | JsonPathBenchmark.benchmarkJsonPathObjectLength | thrpt | 5   | 1680492.243 | ±132492.697  | ops/s |
    

    示例代码可以在here找到。

    【讨论】:

      【解决方案2】:

      你也可以使用jsonpath里面的方法,所以代替

      mockMvc.perform(get(API_URL))
         .andExpect(jsonPath("$.*", hasSize(2)));
      

      你可以的

      mockMvc.perform(get(API_URL))
         .andExpect(jsonPath("$.length()", is(2)));
      

      【讨论】:

        【解决方案3】:

        测试数组的大小:jsonPath("$", hasSize(4))

        统计object的成员:jsonPath("$.*", hasSize(4))


        即测试 API 返回一个包含 4 个项目的 array

        接受值:[1,2,3,4]

        mockMvc.perform(get(API_URL))
               .andExpect(jsonPath("$", hasSize(4)));
        

        测试 API 返回一个包含 2 个成员的 对象

        接受值:{"foo": "oof", "bar": "rab"}

        mockMvc.perform(get(API_URL))
               .andExpect(jsonPath("$.*", hasSize(2)));
        

        我正在使用 Hamcrest 1.3 版和 Spring Test 3.2.5.RELEASE

        hasSize(int) javadoc

        注意: 您需要包含 hamcrest-library 依赖项和 import static org.hamcrest.Matchers.*; 才能使 hasSize() 工作。

        【讨论】:

        • @mattb - 如果使用 Maven,不要添加 hamcrest-all 作为依赖项,而是使用 hamcrest-library: code.google.com/p/hamcrest/wiki/HamcrestDistributables
        • 不知道尺码想买怎么办?
        • @menuka-ishan - 我不认为它已被弃用,根据:MockMvcResultMatchers.jsonPath()javadoc
        • @zygimantus,您必须从源代码或 Web 浏览器开发工具检查响应中计算对象/数组上所有字段的大小。
        • 对于 kotlin,您可能需要像这样添加类型参数:.andExpect(jsonPath("$", hasSize<Array<Any>>(4)))
        【解决方案4】:

        如果您的类路径中没有 com.jayway.jsonassert.JsonAssert(我就是这种情况),则可以通过以下方式进行测试:

        assertEquals(expectedLength, ((net.minidev.json.JSONArray)parsedContent.read("$")).size());
        

        [注意:我假设json的内容总是一个数组]

        【讨论】:

          【解决方案5】:

          今天我自己也在处理这个问题。这似乎没有在可用的断言中实现。但是,有一种方法可以传入org.hamcrest.Matcher 对象。有了它,您可以执行以下操作:

          final int count = 4; // expected count
          
          jsonPath("$").value(new BaseMatcher() {
              @Override
              public boolean matches(Object obj) {
                  return obj instanceof JSONObject && ((JSONObject) obj).size() == count;
              }
          
              @Override
              public void describeTo(Description description) {
                  // nothing for now
              }
          })
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-01-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-10-20
            • 2011-01-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多