ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

REST Assured 73 - How To Ignore Node/S For JSON Comparison In JSONassert

2021-10-06 13:33:18  阅读:226  来源: 互联网

标签:Node Comparison salary Assured married JSON org id name


REST Assured 系列汇总 之 REST Assured 73 - How To Ignore Node/S For JSON Comparison In JSONassert

介绍

我们有时不需要比较 JSON 文档里的所有节点,比较时需忽略一些不匹配的结点。一个现实的例子就是一个时间戳字段,它是变化的,在比较时我们必须忽略这些变化的字段。

前提条件

添加 JSONassert 依赖

<!-- https://mvnrepository.com/artifact/org.skyscreamer/jsonassert -->
<dependency>
    <groupId>org.skyscreamer</groupId>
    <artifactId>jsonassert</artifactId>
    <version>1.5.0</version>
    <scope>test</scope>
</dependency>

请先阅读下面文章,了解 JSONassert Java library 基本概念 ,不同的比较模式和断言 JSON Objects 和 Array。

Introduction To JsonAssert Library

Compare JSON Objects Using JSONassert Library

Compare JSON Arrays Using JSONassert Library

比较时怎么忽略 JSON 中的字段

没有直接的方法去忽略某些字段和属性,我们需要用到 CustomComparator。

 JSONComparator com = new CustomComparator(JSONCompareMode.LENIENT, 
 new Customization("salary", (o1, o2) -&gt; true));

CustomComparator 是一个类,它间接实现 JSONComparator。 Customization 是另外一个类,CustomComparator 的构造函数接收 JSONCompareMode 和一个 Customization 类型的数组。Customization 类的构造函数接收一个包含 euqal() 方法的 ValueMatcher 接口的引用,

// Constructor of CustomComparator
public CustomComparator(JSONCompareMode mode,  Customization... customizations) {
        super(mode);
        this.customizations = Arrays.asList(customizations);
    }

为了忽略某些字段,跟 JSONassert是没有啥关系的,而是显示地让这些忽略的字段断言 PASS。如果我们从第一个 JSON 文档中获取的值为 v1, 第二个 JSON 文档中的值为 v2,v1 可以等于 或 不等于 v2. 我们就像弄了一个代理,显示地将 v1 和 v2 是相等的,或者说是匹配成功的。

上面的代码中,“salary” 是一个 JSON path,“o1” 和 “o2” 分别是从 JSON 文档中获取的值。无条件使得这两个值是相等的,返回 true。

也可以传多个 Customization 引用,因为 CustomComparator 接收的是 Customization 类型的数组。

 JSONComparator com = new CustomComparator(JSONCompareMode.LENIENT, 
 new Customization("salary", (o1, o2) -&gt; true),
 new Customization("age", (o1, o2) -&gt; true)); 

JSONAssert 类的重载方法 assertEquals() 接收 JSONComparator 引用参数。

忽略简单 JSON object 的字段

JSON String 1

{
  "id": 1,
  "first_name": "Amod",
  "last_name": "Mahajan",
  "married": false,
  "salary": 123.45
} 

JSON String 2

{
  "id": 1,
  "first_name": "Amod",
  "last_name": "Mahajan",
  "married": false,
  "salary": 125.45
}

比较时,忽略 “salary” 字段

import org.json.JSONException;
import org.skyscreamer.jsonassert.Customization;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.comparator.CustomComparator;
import org.skyscreamer.jsonassert.comparator.JSONComparator;
 
public class IgnoringFieldsFromSimpleJsonObjects {
 
 public static void main(String[] args) throws JSONException {
 
 String s1 = "{\r\n" + 
 "  \"id\": 1,\r\n" + 
 "  \"first_name\": \"Amod\",\r\n" + 
 "  \"last_name\": \"Mahajan\",\r\n" + 
 "  \"married\": false,\r\n" + 
 "  \"salary\": 123.45\r\n" + 
 "}";
 
 String s2 = "{\r\n" + 
 "  \"id\": 1,\r\n" + 
 "  \"first_name\": \"Amod\",\r\n" + 
 "  \"last_name\": \"Mahajan\",\r\n" + 
 "  \"married\": false,\r\n" + 
 "  \"salary\": 125.45\r\n" + 
 "}";
 
 JSONComparator com = new CustomComparator(JSONCompareMode.LENIENT, 
 new Customization("salary", (o1, o2) -&gt; true));
 
 JSONAssert.assertEquals(s1, s2, com);
 
 }
 
}

忽略嵌套的 JSON Object 的字段

JSON Object 1

 {
  "id": 1,
  "first_name": "Amod",
  "last_name": "Mahajan",
  "married": false,
  "salary": 123.45,
  "address":{
    "permanent" : "KA",
    "city": "Bengaluru"
  }
}

JSON Object 2

{
  "id": 1,
  "first_name": "Amod",
  "last_name": "Mahajan",
  "married": false,
  "salary": 123.45,
  "address":{
    "permanent" : "KA",
    "city": "Katihar"
  }
}

比较时忽略 “address” 字段里面的 “city” 结点。我们需要提供忽略字段正确的 JSON path, “address.city“。

import org.json.JSONException;
import org.skyscreamer.jsonassert.Customization;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.comparator.CustomComparator;
import org.skyscreamer.jsonassert.comparator.JSONComparator;
 
public class IgnoringFieldsFromNestedJsonObjects {
 
 public static void main(String[] args) throws JSONException {
 
 String s1 = "{\r\n" + 
 "  \"id\": 1,\r\n" + 
 "  \"first_name\": \"Amod\",\r\n" + 
 "  \"last_name\": \"Mahajan\",\r\n" + 
 "  \"married\": false,\r\n" + 
 "  \"salary\": 123.45,\r\n" + 
 "  \"address\":{\r\n" + 
 "    \"permanent\" : \"KA\",\r\n" + 
 "    \"city\": \"Bengaluru\"\r\n" + 
 "  }\r\n" + 
 "}";
 
 String s2 = "{\r\n" + 
 "  \"id\": 1,\r\n" + 
 "  \"first_name\": \"Amod\",\r\n" + 
 "  \"last_name\": \"Mahajan\",\r\n" + 
 "  \"married\": false,\r\n" + 
 "  \"salary\": 123.45,\r\n" + 
 "  \"address\":{\r\n" + 
 "    \"permanent\" : \"KA\",\r\n" + 
 "    \"city\": \"Katihar\"\r\n" + 
 "  }\r\n" + 
 "}";
 
 JSONComparator com = new CustomComparator(JSONCompareMode.LENIENT, 
 new Customization("address.city", (o1, o2) -&gt; true));
 
 JSONAssert.assertEquals(s1, s2, com);
 
 }
} 

忽略简单 JSON Array 中的字段

JSON Array 1

[{
  "id": 1,
  "first_name": "Amod",
  "last_name": "Mahajan",
  "married": false,
  "salary": 123.45
},
{
  "id": 2,
  "first_name": "Animesh",
  "last_name": "Prashant",
  "married": true,
  "salary": 223.45
}]

JSON Array 2

[{
  "id": 10,
  "first_name": "Amod",
  "last_name": "Mahajan",
  "married": false,
  "salary": 123.45
},
{
  "id": 2,
  "first_name": "Animesh",
  "last_name": "Prashant",
  "married": true,
  "salary": 223.45
}]

建设我们不想比较数组中第一个 JSON Object 的 ”id“ 字段。我们需要忽略的 JSON path 就是 “[0].id”,但是如果我们选择的是 LENIENT mode,字段是不会忽略的。针对特定索引的元素,我们应该用 STRICT mode。

import org.json.JSONException;
import org.skyscreamer.jsonassert.Customization;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.comparator.CustomComparator;
import org.skyscreamer.jsonassert.comparator.JSONComparator;
 
public class IgnoringFieldsFromSimpleJsonArray {
 
 public static void main(String[] args) throws JSONException {
 
 String s1 = "[{\r\n" + 
 "  \"id\": 1,\r\n" + 
 "  \"first_name\": \"Amod\",\r\n" + 
 "  \"last_name\": \"Mahajan\",\r\n" + 
 "  \"married\": false,\r\n" + 
 "  \"salary\": 123.45\r\n" + 
 "},\r\n" + 
 "{\r\n" + 
 "  \"id\": 2,\r\n" + 
 "  \"first_name\": \"Animesh\",\r\n" + 
 "  \"last_name\": \"Prashant\",\r\n" + 
 "  \"married\": true,\r\n" + 
 "  \"salary\": 223.45\r\n" + 
 "}]";
 
 String s2 = "[{\r\n" + 
 "  \"id\": 10,\r\n" +       
 "  \"first_name\": \"Amod\",\r\n" + 
 "  \"last_name\": \"Mahajan\",\r\n" + 
 "  \"married\": false,\r\n" + 
 "  \"salary\": 123.45\r\n" + 
 "},\r\n" + 
 "{\r\n" + 
 "  \"id\": 2,\r\n" + 
 "  \"first_name\": \"Animesh\",\r\n" + 
 "  \"last_name\": \"Prashant\",\r\n" + 
 "  \"married\": true,\r\n" + 
 "  \"salary\": 223.45\r\n" + 
 "}]";
 
 JSONComparator com = new CustomComparator(JSONCompareMode.STRICT, 
 
 new Customization("[0].id", (o1, o2) -&gt; true));
 
 JSONAssert.assertEquals(s1, s2, com);
 
 }
 
} 

如果我们想忽略所有索引元素,我们可以传递 “[*].id“ JSON path,就可以用 STRICT 或 LENIENT mode 了。

忽略嵌套的 JSON Array 中的字段

JSON Array 1

[
  {
    "id": 1,
    "first_name": "Amod",
    "last_name": "Mahajan",
    "married": false,
    "salary": 123.45,
    "mob": [
      {
        "type": "personal",
        "number": "1234566"
      },
      {
        "type": "business",
        "number": "987654321"
      }
    ]
  },
  {
    "id": 2,
    "first_name": "Animesh",
    "last_name": "Prashant",
    "married": true,
    "salary": 223.45,
    "mob": [
      {
        "type": "personal",
        "number": "1234566"
      },
      {
        "type": "business",
        "number": "987654321"
      }
    ]
  }
]

JSON Array 2

[
  {
    "id": 1,
    "first_name": "Amod",
    "last_name": "Mahajan",
    "married": false,
    "salary": 123.45,
    "mob": [
      {
        "type": "personal",
        "number": "1234566"
      },
      {
        "type": "business",
        "number": "34545646"
      }
    ]
  },
  {
    "id": 2,
    "first_name": "Animesh",
    "last_name": "Prashant",
    "married": true,
    "salary": 223.45,
    "mob": [
      {
        "type": "personal",
        "number": "1234566"
      },
      {
        "type": "business",
        "number": "987654321"
      }
    ]
  }
]

假设想忽略第一个索引元素中第二个 mobile 中的 ”number“ 字段,那么 json path 就是 “[0].mob[1].number“

import org.json.JSONException;
import org.skyscreamer.jsonassert.Customization;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.comparator.CustomComparator;
import org.skyscreamer.jsonassert.comparator.JSONComparator;
 
public class IgnoringFieldsFromNestedJsonArray {
 
 public static void main(String[] args) throws JSONException {
 
 String s1 = "[\r\n" + 
 "  {\r\n" + 
 "    \"id\": 1,\r\n" + 
 "    \"first_name\": \"Amod\",\r\n" + 
 "    \"last_name\": \"Mahajan\",\r\n" + 
 "    \"married\": false,\r\n" + 
 "    \"salary\": 123.45,\r\n" + 
 "    \"mob\": [\r\n" + 
 "      {\r\n" + 
 "        \"type\": \"personal\",\r\n" + 
 "        \"number\": \"1234566\"\r\n" + 
 "      },\r\n" + 
 "      {\r\n" + 
 "        \"type\": \"business\",\r\n" + 
 "        \"number\": \"987654321\"\r\n" + 
 "      }\r\n" + 
 "    ]\r\n" + 
 "  },\r\n" + 
 "  {\r\n" + 
 "    \"id\": 2,\r\n" + 
 "    \"first_name\": \"Animesh\",\r\n" + 
 "    \"last_name\": \"Prashant\",\r\n" + 
 "    \"married\": true,\r\n" + 
 "    \"salary\": 223.45,\r\n" + 
 "    \"mob\": [\r\n" + 
 "      {\r\n" + 
 "        \"type\": \"personal\",\r\n" + 
 "        \"number\": \"1234566\"\r\n" + 
 "      },\r\n" + 
 "      {\r\n" + 
 "        \"type\": \"business\",\r\n" + 
 "        \"number\": \"987654321\"\r\n" + 
 "      }\r\n" + 
 "    ]\r\n" + 
 "  }\r\n" + 
 "]";
 
 String s2 = "[\r\n" + 
 "  {\r\n" + 
 "    \"id\": 1,\r\n" + 
 "    \"first_name\": \"Amod\",\r\n" + 
 "    \"last_name\": \"Mahajan\",\r\n" + 
 "    \"married\": false,\r\n" + 
 "    \"salary\": 123.45,\r\n" + 
 "    \"mob\": [\r\n" + 
 "      {\r\n" + 
 "        \"type\": \"personal\",\r\n" + 
 "        \"number\": \"1234566\"\r\n" + 
 "      },\r\n" + 
 "      {\r\n" + 
 "        \"type\": \"business\",\r\n" + 
 "        \"number\": \"34545646\"\r\n" + 
 "      }\r\n" + 
 "    ]\r\n" + 
 "  },\r\n" + 
 "  {\r\n" + 
 "    \"id\": 2,\r\n" + 
 "    \"first_name\": \"Animesh\",\r\n" + 
 "    \"last_name\": \"Prashant\",\r\n" + 
 "    \"married\": true,\r\n" + 
 "    \"salary\": 223.45,\r\n" + 
 "    \"mob\": [\r\n" + 
 "      {\r\n" + 
 "        \"type\": \"personal\",\r\n" + 
 "        \"number\": \"1234566\"\r\n" + 
 "      },\r\n" + 
 "      {\r\n" + 
 "        \"type\": \"business\",\r\n" + 
 "        \"number\": \"987654321\"\r\n" + 
 "      }\r\n" + 
 "    ]\r\n" + 
 "  }\r\n" + 
 "]";
 
 System.out.println(s1);
 System.out.println(s2);
 JSONComparator com = new CustomComparator(JSONCompareMode.STRICT, 
 new Customization("[0].mob[1].number", (o1, o2) -&gt; true));
 
 JSONAssert.assertEquals(s1, s2, com);
 
 }
 
} 

注意,比较时如果忽略的 JSON path 在 JSON 文档中找不到, 测试将会失败。

标签:Node,Comparison,salary,Assured,married,JSON,org,id,name
来源: https://blog.csdn.net/wumingxiaoyao/article/details/120623409

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有