【问题标题】:REST assured - compare two JSON objects放心 - 比较两个 JSON 对象
【发布时间】:2020-07-30 13:58:30
【问题描述】:

假设 GET 请求返回给我一些 JSON 对象:

{
 "a": 1, "b": 2, "c": 3, "date": "current_date"
}

我手里有一个类似的对象,我想检查它是否与键“a”、“b”、“c”相同,并忽略“日期”键。

我该怎么做?

【问题讨论】:

  • 使用方法的对象进行比较,在该对象中传递另一个对象而不检查date 字段。
  • “使用方法的对象”是什么意思?

标签: java rest-assured web-api-testing


【解决方案1】:

我一直在使用JsonUnit,它真的很有帮助

String json1 = "{\r\n" + "  \"a\": 1,\r\n" + "  \"b\": 2,\r\n" + "  \"c\": 3,\r\n"
            + " \"date\": \"30-07-2020\"\r\n" + "}";

String json2 = "{\r\n" + "  \"a\": 1,\r\n" + "  \"b\": 2,\r\n" + "  \"c\": 3,\r\n"
            + " \"date\": \"31-07-2020\"\r\n" + "}";

assertThatJson(json1).whenIgnoringPaths("date").isEqualTo(json2);

静态导入:

import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;

依赖:

    <dependency>
        <groupId>net.javacrumbs.json-unit</groupId>
        <artifactId>json-unit-assertj</artifactId>
        <version>2.18.1</version>
        <scope>test</scope>
    </dependency>

您还必须将json.orgJackson 1.xJackson 2.xJohnzonGson 添加到类路径中

我用Jackson

【讨论】:

    【解决方案2】:

    您可以将其转换为 Json 对象并删除不需要的键。详情点击链接:Remove key from a Json inside a JsonObject

    【讨论】:

    • 然后呢?如何比较这两个对象?
    【解决方案3】:

    我发现rest-assured有一些有趣的功能。

    你可以这样做:

    @Test
    public void test() {
       get("/xxxx").then().statusCode(200).assertThat()
      .body("a", equalTo(1)); 
    }
    

    更多信息here

    【讨论】:

      【解决方案4】:

      您可以将 JSON 转换为 JS 对象,然后比较该对象的每个属性,如果该属性的键不等于“日期”

      在下面的代码中比较 obj1obj2 并忽略 date 属性。 如果它们相同,则打印“相同”,如果不同,则打印“不相同”(忽略 date 属性)

      var obj1 = JSON.parse ('{ "a":"1","b":"2", "c":"3", "date":"current_date"}' );
      
      var obj2 = JSON.parse ('{ "a":"1","b":"2", "c":"3", "date":"another_date"}' );
      
      let s1 = Object.keys(obj1).length; // length of obj1
      let s2 = Object.keys(obj2).length; // length of obj2
      
      let identical = true ;
      
      for ( let i = 0 ; i < s1 ; i ++ ){
        if (i >= s2) {
          identical = false ;
          break ;
        }
        
        let current_key = Object.keys(obj1)[i];
        let current_value = obj1[current_key];
        
        if (current_key.localeCompare("date") != 0){
           if (current_value.localeCompare(obj2[current_key]) != 0){
             identical = false ;
             break;
           }
        }
       
      }
      
      if (identical){
        console.log ("Identical");
      }else {
        console.log ("Not identical");
      }

      【讨论】:

        【解决方案5】:
        1. 使用AssertJ ignoring fields in the comparison
          因为需要将 json 从响应(对于 Spring 测试:MvcResult.getResponse().getContentAsString())反序列化为 Object。 可以使用REST Assured Content-Type based Deserialization 反序列化 json 响应
        2. 使用非严格比较 JSONassert
          为了不手动创建 json,可以使用 Jackson ObjectMapper 序列化预期对象。对于字段排除:
        Map<String, Object> map = objectMapper.convertValue(obj, new TypeReference<Map<String, Object>>() {});
        map.remove(...);
        objectMapper.writeValueAsString(obj)
        

        【讨论】:

          猜你喜欢
          • 2014-03-02
          • 1970-01-01
          • 1970-01-01
          • 2017-11-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-26
          • 2018-03-28
          相关资源
          最近更新 更多