Open ezredd opened 9 years ago
+1, having this problem as well.
I actually solved this problem. All you need to do is write a class to override DefaultComparator which will override the methods
and then if you have an instance of your comparator (let's call it dblComparator) when you compare 2 json all you need is to make use of the method
hope this helps!
if i have time i could try to submit a pull request to have my class available to everyone
Good info above. We just came across the same problem and came up with the same solution. For the benefit of other googlers, here's some code to cut and paste, that's an example of overriding the DefaultComparator for allowing fuzziness on doubles in Json.
public class LooseyGooseyDoublesJSONComparator extends DefaultComparator {
private Double howLoosey;
public LooseyGooseyDoublesJSONComparator(JSONCompareMode mode, Double howLoosey) {
super(mode);
this.howLoosey = howLoosey;
}
public static void assertEquals( String expected, String actual, double howLoosey) throws JSONException {
JSONCompareResult result = JSONCompare.compareJSON(expected, actual, new LooseyGooseyDoublesJSONComparator(JSONCompareMode.LENIENT, howLoosey));
if (result.failed()) {
throw new AssertionError(result.getMessage());
}
}
@Override
public void compareValues(String prefix, Object expectedValue, Object actualValue, JSONCompareResult result)
throws JSONException {
if (expectedValue instanceof Number && actualValue instanceof Number) {
if (Math.abs(((Number)expectedValue).doubleValue() - ((Number)actualValue).doubleValue()) > howLoosey){
result.fail(prefix, expectedValue, actualValue);
}
} else if (expectedValue.getClass().isAssignableFrom(actualValue.getClass())) {
if (expectedValue instanceof JSONArray) {
compareJSONArray(prefix, (JSONArray) expectedValue, (JSONArray) actualValue, result);
} else if (expectedValue instanceof JSONObject) {
compareJSON(prefix, (JSONObject) expectedValue, (JSONObject) actualValue, result);
} else if (!expectedValue.equals(actualValue)) {
result.fail(prefix, expectedValue, actualValue);
}
} else {
result.fail(prefix, expectedValue, actualValue);
}
}
}
You can use the static assert to do the comparison:
LooseyGooseyDoublesJSONComparator.assertEquals( expectedJsonResponse, actualJsonResponse, 0.00001d);
@davedupplaw your comment helped me a lot, it was exactly what I needed, thanks!
Please correct me if I am wrong but I found an even shorter solution:
public class JSONComparator extends DefaultComparator {
private final double epsilon;
public JSONComparator(JSONCompareMode mode, double epsilon) {
super(mode);
this.epsilon = epsilon;
}
@Override
protected boolean areNotSameDoubles(Object expectedValue, Object actualValue) {
return Math.abs(((Number) expectedValue).doubleValue() - ((Number) actualValue).doubleValue()) >= epsilon;
}
}
JSONAssert.assertEquals(expected, actual, new JSONComparator(JSONCompareMode.STRICT, 1E-8));
maybe it is possible to do with the current implementation however if that's the case then it would be great to add this as an example in the cookbook ?
thanks a lot anyways for this very nice tool!!