一直在纠结的一个问题:我在公司一开始写接口测试用例的时候,都是按接口规则,预期值直接从库里查数据然后拼接json出来和实际接口返回json进行断言,但这种方式工作量太大,越到后来我就直接将接口返回值复制粘贴到预期结果里了。但这种方式我越想越觉得没有任何意义。我就在想,是不是可以将必须校验的字段单独拎出来,然后和预期结果比,基于该思路,我今天想了一个比较json的类。
接口返回的json串是实际结果,我们给的json串是包含我们校验的key-value,没必要校验的key就不写在json中了。不包含的key必不会影响校验结果,只有预期的json串中的value值和实际json中的value值匹配不上,才会返回false。
package com.course.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.log4j.Log4j;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@Log4j
public class JsonUtil {
/**
* 判断实际结果和预期结果是否一致,在预期结果中可以去除不需要验证的key
*
* @param actualJson
* @param exceptedJson
* @return
*/
public static Boolean cmpJsonObject(JSONObject actualJson, JSONObject exceptedJson) {
List<String> reultList = new LinkedList<>();
for (Map.Entry<String, Object> actualEntry : actualJson.entrySet()) {
for (Map.Entry<String, Object> exceptedEntry : exceptedJson.entrySet()) {
if (actualEntry.getKey().equals(exceptedEntry.getKey())) {
if (!actualEntry.getValue().equals(exceptedEntry.getValue())) {
reultList.add(actualEntry.getKey());
}
}
}
}
if (reultList.size() > 0) {
log.info("共有--->" + reultList.size() + "<---对键值对不匹配");
for (String s : reultList) {
log.info(reultList.indexOf(s) + ":");
log.info("实际值:" + actualJson.getString(s));
log.info("预期值:" + exceptedJson.getString(s));
}
return false;
} else {
return true;
}
}
/**
* @param actualJsonArray
* @param exceptedJsonArray
* @return
*/
public static Boolean cmpJsonArray(JSONArray actualJsonArray, JSONArray exceptedJsonArray) {
List<String> reultList = new LinkedList<>();
if (actualJsonArray.size() == exceptedJsonArray.size()) {
for (int i = 0; i < actualJsonArray.size(); i++) {
if (verifyJsonObject(actualJsonArray.getString(i)) && verifyJsonObject(exceptedJsonArray.getString(i))) {
if (!cmpJsonObject(actualJsonArray.getJSONObject(i), exceptedJsonArray.getJSONObject(i))) {
reultList.add(String.valueOf(i));
}
} else {
if (!actualJsonArray.get(i).equals(exceptedJsonArray.get(i))) {
reultList.add(String.valueOf(i));
}
}
}
}
if (reultList.size() > 0) {
log.info("共有--->" + reultList.size() + "<---对键值对不匹配");
for (String s : reultList) {
log.info(reultList.indexOf(s) + ":");
log.info("实际值:" + actualJsonArray.getString(Integer.valueOf(s)));
log.info("预期值:" + exceptedJsonArray.getString(Integer.valueOf(s)));
}
return false;
} else {
return true;
}
}
/**
* 校验是否是json串
*
* @param jsonString
* @return Boolean
*/
private static Boolean verifyJson(String jsonString) {
try {
JSON.parse(jsonString);
return true;
} catch (Exception e) {
return false;
}
}
/**
* 校验是否是JSONObject类型的json
*
* @param jsonString
* @return Boolean
*/
public static Boolean verifyJsonObject(String jsonString) {
if (!verifyJson(jsonString)) {
return false;
}
try {
JSONObject.parseObject(jsonString);
return true;
} catch (Exception e) {
return false;
}
}
/**
* 校验是否是JSONArray类型的json
*
* @param jsonString
* @return Boolean
*/
public static Boolean verifyJsonArray(String jsonString) {
if (!verifyJson(jsonString)) {
return false;
}
try {
JSONArray.parseArray(jsonString);
return true;
} catch (Exception e) {
return false;
}
}
}
我使用的如下方法进行测试的
@Test
public void cmpJson() {
String str1 = "json";
String str2 = "json";
JSONObject jsonObject1 = JSONObject.parseObject(str1);
JSONObject jsonObject2 = JSONObject.parseObject(str2);
Assert.assertEquals(java.util.Optional.of(JsonUtil.cmpJsonObject(jsonObject1, jsonObject2)), true);
JSONArray jsonArray1 = new JSONArray();
JSONArray jsonArray2 = new JSONArray();
jsonArray1.add("first");
jsonArray1.add("second");
jsonArray2.add("first");
jsonArray2.add("second");
Assert.assertEquals(JsonUtil.cmpJsonArray(jsonArray1, jsonArray2), java.util.Optional.of(true));
}