REST Assured 系列汇总 之 REST Assured 68 - Compare Two JSON Using Jackson – Java Library
介绍
API 测试,有时需要比较两个 JSON。例如:我们想每次从一个 API返回的结果是一样的,或部分 response body 结果是不变的,就可以直接比较已经存在的 JSON response,省去了写大量逻辑代码去断言。
有许多好的 Java 库可以用来比较,本文我们主要了解用 Jackson 库来比较两个 JSON response。
前提条件
添加 jackson databind依赖
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
JsonNode equals()
Jackson API 提供一个抽象类 JsonNode, JsonNode 有一个抽象方法 equals() 可以用来比较 node objects。node objects 的相等是指 node 的整表层级结点都相等。equals() 抽象方法是被 ObjectNode 和 ArrayNode 类实现的。
我们首先需要将给定的 JSON 转换成 JsonNode (或 ObjectNode 或 ArrayNode),然后调用 equals() 即可。
注意点:
如果 JSON nodes 相等,那么 equals() 方法将返回 true,但是 JSON nodes 里的节点顺序是不关心的。但是如果是 JSON Array,关心顺序,顺序不同将影响两个 JSON array 的相等。
比较 JSON Objects
import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class CompareJsonObjects {
String JsonObject1;
String jsonObject2;
ObjectMapper objectMapper;
JsonNode jsonNode1;
JsonNode jsonNode2;
@Test
public void compareTwoJsonObjects() throws JsonMappingException, JsonProcessingException
{
JsonObject1 = "{\r\n" +
" \"firstName\" : \"Amod\",\r\n" +
" \"lastName\" : \"Mahajan\"\r\n" +
"}";
jsonObject2 = "{\r\n" +
" \"firstName\" : \"Amod\",\r\n" +
" \"lastName\" : \"Mahajan\"\r\n" +
"}";
objectMapper = new ObjectMapper();
jsonNode1 = objectMapper.readTree(JsonObject1);
jsonNode2 = objectMapper.readTree(jsonObject2);
// Checking if both json objects are same
System.out.println(jsonNode1.equals(jsonNode2));
}
@Test
public void compareTwoJsonObjectsWithDifferentOrderOfRootElements() throws JsonMappingException, JsonProcessingException
{
// Change in order of elements does not impact
JsonObject1 = "{\r\n" +
" \"firstName\" : \"Amod\",\r\n" +
" \"lastName\" : \"Mahajan\"\r\n" +
"}";
jsonObject2 = "{\r\n" +
" \"lastName\" : \"Mahajan\",\r\n" +
" \"firstName\" : \"Amod\"\r\n" +
" \r\n" +
"}";
jsonNode1 = objectMapper.readTree(JsonObject1);
jsonNode2 = objectMapper.readTree(jsonObject2);
System.out.println(jsonNode1.equals(jsonNode2));
}
@Test
public void compareTwoNestedJsonObjects() throws JsonMappingException, JsonProcessingException
{
// Nested json objects can also be compared with equals method
JsonObject1 = "{\r\n" +
" \"lastName\": \"Mahajan\",\r\n" +
" \"firstName\": \"Amod\",\r\n" +
" \"address\": {\r\n" +
" \"city\": \"Katihar\",\r\n" +
" \"state\": \"Bihar\"\r\n" +
" }\r\n" +
"}";
jsonObject2 = "{\r\n" +
" \"lastName\": \"Mahajan\",\r\n" +
" \"firstName\": \"Amod\",\r\n" +
" \"address\": {\r\n" +
" \"city\": \"Katihar\",\r\n" +
" \"state\": \"Bihar\"\r\n" +
" }\r\n" +
"}";
jsonNode1 = objectMapper.readTree(JsonObject1);
jsonNode2 = objectMapper.readTree(jsonObject2);
System.out.println(jsonNode1.equals(jsonNode2));
}
}
结果:JSON Object 相等,顺序可以不同
true
true
true
比较 JSON Arrays
import org.junit.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class CompareJsonArrays {
String jsonArray1;
String jsonArray2;
ObjectMapper objectMapper;
JsonNode jsonNode1;
JsonNode jsonNode2;
@Test
public void compareTwoJsonArrays() throws JsonMappingException, JsonProcessingException
{
jsonArray1 = "[\r\n" +
" {\r\n" +
" \"lastName\": \"Mahajan\",\r\n" +
" \"firstName\": \"Amod\",\r\n" +
" \"address\": {\r\n" +
" \"city\": \"Katihar\",\r\n" +
" \"state\": \"Bihar\"\r\n" +
" }\r\n" +
" },\r\n" +
" {\r\n" +
" \"lastName\": \"Animesh\",\r\n" +
" \"firstName\": \"Prashant\",\r\n" +
" \"address\": {\r\n" +
" \"city\": \"Kolkata\",\r\n" +
" \"state\": \"WB\"\r\n" +
" }\r\n" +
" }\r\n" +
"]";
jsonArray2 = "[\r\n" +
" {\r\n" +
" \"lastName\": \"Mahajan\",\r\n" +
" \"firstName\": \"Amod\",\r\n" +
" \"address\": {\r\n" +
" \"city\": \"Katihar\",\r\n" +
" \"state\": \"Bihar\"\r\n" +
" }\r\n" +
" },\r\n" +
" {\r\n" +
" \"lastName\": \"Animesh\",\r\n" +
" \"firstName\": \"Prashant\",\r\n" +
" \"address\": {\r\n" +
" \"city\": \"Kolkata\",\r\n" +
" \"state\": \"WB\"\r\n" +
" }\r\n" +
" }\r\n" +
"]";
objectMapper = new ObjectMapper();
jsonNode1 = objectMapper.readTree(jsonArray1);
jsonNode2 = objectMapper.readTree(jsonArray2);
// Checking if both json objects are same
System.out.println(jsonNode1.equals(jsonNode2));
}
@Test
public void compareTwoJsonArraysWithDifferentOrderOfElements() throws JsonMappingException, JsonProcessingException
{
// Change in order of elements in array will impact and it will not be considered same
jsonArray1 = "[\r\n" +
" {\r\n" +
" \"lastName\": \"Mahajan\",\r\n" +
" \"firstName\": \"Amod\",\r\n" +
" \"address\": {\r\n" +
" \"city\": \"Katihar\",\r\n" +
" \"state\": \"Bihar\"\r\n" +
" }\r\n" +
" },\r\n" +
" {\r\n" +
" \"lastName\": \"Animesh\",\r\n" +
" \"firstName\": \"Prashant\",\r\n" +
" \"address\": {\r\n" +
" \"city\": \"Kolkata\",\r\n" +
" \"state\": \"WB\"\r\n" +
" }\r\n" +
" }\r\n" +
"]";
jsonArray2 = "[\r\n" +
" {\r\n" +
" \"lastName\": \"Animesh\",\r\n" +
" \"firstName\": \"Prashant\",\r\n" +
" \"address\": {\r\n" +
" \"city\": \"Kolkata\",\r\n" +
" \"state\": \"WB\"\r\n" +
" }\r\n" +
" },\r\n" +
" {\r\n" +
" \"lastName\": \"Mahajan\",\r\n" +
" \"firstName\": \"Amod\",\r\n" +
" \"address\": {\r\n" +
" \"city\": \"Katihar\",\r\n" +
" \"state\": \"Bihar\"\r\n" +
" }\r\n" +
" }\r\n" +
"]";
jsonNode1 = objectMapper.readTree(jsonArray1);
jsonNode2 = objectMapper.readTree(jsonArray2);
System.out.println(jsonNode1.equals(jsonNode2));
}
}
结果:JSON Array中顺序不同,也是不相等。
true
false