REST Assured 70 - Compare JSON Objects Using JSONassert Library

REST Assured 系列汇总 之 REST Assured 70 - Compare JSON Objects Using JSONassert Library

介绍

API 测试,有时需要比较两个 JSON。例如:我们想每次从一个 API返回的结果是一样的,或部分 response body 结果是不变的,就可以直接比较已经存在的 JSON response,省去了写大量逻辑代码去断言。

有许多好的 Java 库可以用来比较,前面我们用 Jackson 库 比较两个 JSONs,本文我们主要了解用 JSONassert 库来比较两个 JSON response。

前提条件

添加 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 基本概念 和不同的比较模式。

Introduction To JsonAssert Library

assertEquals() 方法

JSONassert 提供了很多静态重载的 assertEquals() 方法
JSONassert provides multiple static overloaded assertEquals() method. We will see most of them.

Lenient mode

前面的文章我们了解到,在 Lenient 模式中,extensibility 是允许的,没有严格的顺序要求,我们通过例子来了解一下。

比较两个一样的 JSON Object
assertEquals() 方法会 PASS,因为两个 JSON 字符串是相同的。

@Test
	public void exactSameJson() throws JSONException {
    
    
		
		String jsoNobject1 = "{\r\n" + 
				"  \"firstName\" : \"Amod\",\r\n" + 
				"  \"lastName\": \"Mahajan\"\r\n" + 
				"}";
		
		String jsonObject2 = "{\r\n" + 
				"  \"firstName\" : \"Amod\",\r\n" + 
				"  \"lastName\": \"Mahajan\"\r\n" + 
				"}";
		
		// Lenient mode - extensible and no strict ordering
		JSONAssert.assertEquals(jsoNobject1, jsonObject2, JSONCompareMode.LENIENT);
	}

比较两个 JSON Objects,字段相同,只是顺序不同
下面例子,两个 JSON 有相同的字段,字段对应的值也是相同的,但是字段排列顺序不同。因为 Lenient 模式,strict order 是没有应用的,而且 strict order 只对 JSON Array 有意义,而对 JSON objects 没有效果,所以 assertEquals() 会 PASS。

@Test
	public void exactSameJsonWIthDifferentOrder() throws JSONException {
    
    
		
		String jsoNobject1 = "{\r\n" + 
				"  \"firstName\" : \"Amod\",\r\n" + 
				"  \"lastName\": \"Mahajan\"\r\n" + 
				"}";
		
		String jsonObject2 = "{\r\n" + 
				"  \"lastName\": \"Mahajan\",\r\n" + 
				"  \"firstName\": \"Amod\"\r\n" + 
				"}";
		
		// Lenient mode - extensible and no strict ordering but ordering will not be applicable for 
		// JSON objects
		JSONAssert.assertEquals(jsoNobject1, jsonObject2, JSONCompareMode.LENIENT);
	}

比较两个 JSONs,字段相同,但是字段对应的值不同
因为值不匹配,assertEquals() 会 FAIL

@Test
	public void sameFieldsWithDifferentValues() throws JSONException {
    
    
		
		String jsoNobject1 = "{\r\n" + 
				"  \"firstName\" : \"Amod\",\r\n" + 
				"  \"lastName\": \"Mahajan\"\r\n" + 
				"}";
		
		String jsonObject2 = "{\r\n" + 
				"  \"lastName\": \"Mahajan\",\r\n" + 
				"  \"firstName\": \"Rahul\"\r\n" + 
				"}";
		
		JSONAssert.assertEquals(jsoNobject1, jsonObject2, JSONCompareMode.LENIENT);
	}

结果:

FAILED: sameFieldsWithDifferentValues
java.lang.AssertionError: firstName
Expected: Amod
     got: Rahul

比较两个 JSONs,字段相同,但是值的数据类型不同
这个例子比较重要,用 JSONassert 比较 JSONs 要知道 “18” 和 18 是不同的。看上去都是 18,但是数据类型不一样。

@Test
	public void unmatchedDataType() throws JSONException {
    
    
		
		String jsoNobject1 = "{\r\n" + 
				"  \"lastName\": \"Mahajan\",\r\n" + 
				"  \"firstName\": \"Amod\",\r\n" + 
				"  \"age\": \"18\"\r\n" + 
				"}";
		
		String jsonObject2 = "{\r\n" + 
				"  \"lastName\": \"Mahajan\",\r\n" + 
				"  \"firstName\": \"Amod\",\r\n" + 
				"  \"age\": 18\r\n" + 
				"}";
		// First json has 18 as string while second json has 18 as int
		JSONAssert.assertEquals(jsoNobject1, jsonObject2, JSONCompareMode.LENIENT);
	}

结果:

FAILED: unmatchedDataType
java.lang.AssertionError: age
Expected: 18
     got: 18

Strict Mode

如果我们不想选择 extensibility, 而是想准确比较两个 JSONs,我们可以用 strict mode。

@Test
	public void strictMatchExample1() throws JSONException {
    
    
		
		String jsoNobject1 = "{\r\n" + 
				"  \"firstName\" : \"Amod\",\r\n" + 
				"  \"lastName\": \"Mahajan\"\r\n" + 
				"}";
		
		String jsonObject2 = "{\r\n" + 
				"  \"firstName\" : \"Amod\",\r\n" + 
				"  \"lastName\": \"Mahajan\",\r\n" + 
				"  \"age\": 28\r\n" + 
				"}";
		
		JSONAssert.assertEquals(jsoNobject1, jsonObject2, JSONCompareMode.STRICT);
	}

结果:

FAILED: strictMatchExample1
java.lang.AssertionError: 
Unexpected: age

用重载 assertEquals() method

前面的例子,assertEquals() 方法接收的都是 JSON 字符串,我们也可以传递 JSONObject 或 JSONArray,这样让你有更多的选择用来比较 JSONs。

import org.json.JSONException;
import org.json.JSONObject;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.junit.Test;
 
public class LinentMatchWithJsonObject {
    
    
	
	@Test
	public void matchJsonObject() throws JSONException {
    
    
		
		JSONObject jsonObject1 = new JSONObject();
		jsonObject1.put("firstName", "Amod");
		jsonObject1.put("lastName", "Mahajan");
		
		
		JSONObject jsonObject2 = new JSONObject();
		jsonObject2.put("firstName", "Amod");
		jsonObject2.put("lastName", "Mahajan");
		
		
		JSONAssert.assertEquals(jsonObject1, jsonObject2, JSONCompareMode.LENIENT);
	}
}

如果不想用 JSONCompareMode 枚举,也可以用另外一个重载方法 assertEquals() 方法,通过 boolean 参数来传递 mode,默认是非 strict 的,如果想选择 strict,传递 true 值。

assertEquals(JSONObject expected, JSONObject actual, boolean strict) 

如果两个 JSONs 不一样,也可以定制化消息:

import org.json.JSONException;
import org.json.JSONObject;
import org.skyscreamer.jsonassert.JSONAssert;
import org.testng.annotations.Test;
 
public class LinentMatchWithJsonObject {
    
    
	
	@Test
	public void matchJsonObject() throws JSONException {
    
    
		
		JSONObject jsonObject1 = new JSONObject();
		jsonObject1.put("firstName", "Amod");
		jsonObject1.put("lastName", "Mahajan");
		
		
		JSONObject jsonObject2 = new JSONObject();
		jsonObject2.put("firstName", "Rahul");
		jsonObject2.put("lastName", "Mahajan");
		
		
		//JSONAssert.assertEquals(jsonObject1, jsonObject2, false);
		
		JSONAssert.assertEquals("Jsons are not equal", jsonObject1, jsonObject2, false);
	}
}

结果:

FAILED: matchJsonObject
java.lang.AssertionError: Jsons are not equal firstName
Expected: Amod
     got: Rahul

Handling Error using try-catch

当比较失败时,会抛出 AssertionError,可以用 catch 来捕获异常。

import org.json.JSONException;
import org.json.JSONObject;
import org.skyscreamer.jsonassert.JSONAssert;
import org.testng.annotations.Test;
 
public class ErrorHandlingJSONassert {
    
    
	
	@Test
	public void errorHandling() throws JSONException {
    
    
		
		JSONObject jsonObject1 = new JSONObject();
		jsonObject1.put("firstName", "Amod");
		jsonObject1.put("lastName", "Mahajan");
		
		
		JSONObject jsonObject2 = new JSONObject();
		jsonObject2.put("firstName", "Rahul");
		jsonObject2.put("lastName", "Mahajan");
		
		try {
    
    
		JSONAssert.assertEquals(jsonObject1, jsonObject2, false);
		}catch(Error e)
		{
    
    
			System.out.println("Error occured as JSONs are not same.");
		}
	}
 
}

结果:

Error occured as JSONs are not same.
PASSED: errorHandling

猜你喜欢

转载自blog.csdn.net/wumingxiaoyao/article/details/120613174