[SoapUI] 比较JSON Response

比较两个JSON, ID是数字时,处理成统一的格式:只保留小数点后5位

package direct;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.JSONCompareResult;
import org.skyscreamer.jsonassert.comparator.DefaultComparator;
import org.skyscreamer.jsonassert.JSONCompare;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

import static org.skyscreamer.jsonassert.comparator.JSONCompareUtil.*;

/**
 * Created by jenny zhang on 2017/9/19.
 */
public class LooseyJSONComparator extends DefaultComparator {
    private int scale;
	String extraInfo;
	def log;

    public LooseyJSONComparator(JSONCompareMode mode, int scale,String extraInfo,def log) {
        super(mode);
        this.scale = scale;
		this.extraInfo = extraInfo;
		this.log = log;
    }
	
	public static void assertEquals( String expected, String actual, int scale, String extraInfo, def log) throws JSONException {
        JSONCompareResult result = JSONCompare.compareJSON(expected, actual, new LooseyJSONComparator(JSONCompareMode.NON_EXTENSIBLE,scale,extraInfo,log));
        if (result.failed()) {
			def failMessage = result.getMessage();
            throw new AssertionError(extraInfo + failMessage);
        }
		else{
			log.info "pass";
		}
    }

    @Override
    protected void compareJSONArrayOfJsonObjects(String key, JSONArray expected, JSONArray actual, JSONCompareResult result) throws JSONException {
        String uniqueKey = findUniqueKey(expected);
        if (uniqueKey == null || !isUsableAsUniqueKey(uniqueKey, actual)) {
            // An expensive last resort
            recursivelyCompareJSONArray(key, expected, actual, result);
            return;
        }
		
		Map<Object, JSONObject> expectedValueMap = arrayOfJsonObjectToMap(expected, uniqueKey, log);
		Map<Object, JSONObject> actualValueMap = arrayOfJsonObjectToMap(actual, uniqueKey, log);

        for (Object id : expectedValueMap.keySet()) {
            if (!actualValueMap.containsKey(id)) {
                result.missing(formatUniqueKey(key, uniqueKey, expectedValueMap.get(id).get(uniqueKey)),
                        expectedValueMap.get(id));
                continue;
            }
            JSONObject expectedValue = expectedValueMap.get(id);
            JSONObject actualValue = actualValueMap.get(id);
            compareValues(formatUniqueKey(key, uniqueKey, id), expectedValue, actualValue, result);
        }
        for (Object id : actualValueMap.keySet()) {
            if (!expectedValueMap.containsKey(id)) {
                result.unexpected(formatUniqueKey(key, uniqueKey, actualValueMap.get(id).get(uniqueKey)), actualValueMap.get(id));
            }
        }
    }

    private String getCompareValue(String value) {
		try{
			return new BigDecimal(value).setScale(scale, RoundingMode.HALF_UP).toString();
		} catch (NumberFormatException e) {
			return value;   //value may = NaN, in this case, return value directly.
		}
    }

    private boolean isNumeric(Object value) {
        try {
            Double.parseDouble(value.toString());
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    public Map<Object, JSONObject> arrayOfJsonObjectToMap(JSONArray array, String uniqueKey,def log) throws JSONException {
        Map<Object, JSONObject> valueMap = new HashMap<Object, JSONObject>();
        for (int i = 0; i < array.length(); ++i) {
            JSONObject jsonObject = (JSONObject) array.get(i);
            Object id = jsonObject.get(uniqueKey);
            id = isNumeric(id) ? getCompareValue(id.toString()) : id;
            valueMap.put(id, jsonObject);
        }
        return valueMap;
    }

    @Override
    public void compareValues(String prefix, Object expectedValue, Object actualValue, JSONCompareResult result) throws JSONException {
        if (areLeaf(expectedValue, actualValue)) {
            if (isNumeric(expectedValue) && isNumeric(actualValue)) {
                if (getCompareValue(expectedValue.toString()).equals(getCompareValue(actualValue.toString()))) {
                    result.passed();
                } else {
                    result.fail(prefix, expectedValue, actualValue);
                }
                return;
            }
        }
        super.compareValues(prefix, expectedValue, actualValue, result);
    }

    private boolean areLeaf(Object expectedValue, Object actualValue) {
		boolean isLeafExpectedValue = !(expectedValue instanceof JSONArray)&&!(expectedValue instanceof JSONObject);
		boolean isLeafActualValue = !(actualValue instanceof JSONArray)&&!(actualValue instanceof JSONObject);
		return isLeafExpectedValue&&isLeafActualValue;
    }
}

  

posted on 2017-09-28 17:33  张缤分  阅读(305)  评论(0编辑  收藏  举报

导航