skyscreamer / JSONassert

Write JSON unit tests in less code. Great for testing REST interfaces.
http://jsonassert.skyscreamer.org
Apache License 2.0
1k stars 197 forks source link

Fix numerical comparisons #23

Closed derrickburns closed 11 years ago

derrickburns commented 11 years ago

If a field appears to be an integer, and a double of the same value appears, JsonAssert reports something like:

Values of geo.coordinates[0] have different types: expected java.lang.Integer, but got java.lang.Double ; Values of geo.coordinates[1] have different types: expected java.lang.Integer, but got java.lang.Double

In this case, the value expected value is 0 (an integer) and the given value is 0.0 (a double).

The key observation is that the double can be coerced into the integer without loss of precision, and therefore should be allowed.

carterpage commented 11 years ago

This would be a good feature to integrate into something toggleable like the JAConstraint mentioned in #15 . Assigning to myself.

hertzsprung commented 11 years ago

The current failure message seems reasonable to me. Can you explain some more about your use case; is it not simple enough to expect the double value 0.0?

That said, this does highlight a potential problem comparing double values (you really need to compare within some tolerance delta)

derrickburns commented 11 years ago

The original/expected value is 0. The tested value is 0.0. That issue is that the original value is interpreted as an integer, but it is simultaneously a double. If it were interpreted also a double there would be no error message.

On Jan 29, 2013, at 1:32 PM, James Shaw notifications@github.com wrote:

The current failure message seems reasonable to me. Can you explain some more about your use case; is it not simple enough to expect the double value 0.0?

That said, this does highlight a potential problem comparing double values (you really need to compare within some tolerance delta)

— Reply to this email directly or view it on GitHub.

hertzsprung commented 11 years ago

Derrick, does it work if you change the expected value to 0.0? Are there reasons that it's not straightforward for you to do that?

derrickburns commented 11 years ago

Yes and yes. I am using Jackson to parse terabytes of data that I do not generate. I read the data using Jackson into POJOs. I decompose the data into "shreds". To test my code, I reassemble the shreds into POJOs and then serialize the new POJOs using Jackson into Json. I then use jsonaasert to compare the two.

To get the exact same serialization, I'd have to write my own Jackson serializer to tell it to serialize doubles that are interger valued as integers.

On Jan 29, 2013, at 1:42 PM, James Shaw notifications@github.com wrote:

Derrick, does it work if you change the expected value to 0.0? Are there reasons that it's not straightforward for you to do that?

— Reply to this email directly or view it on GitHub.

hertzsprung commented 11 years ago

Thanks Derrick. Just to clarify for me, your input JSON (which isn't under your control) has a mixture of integer and double values for the same field whereas your output JSON (which is under your control) always use doubles?

derrickburns commented 11 years ago

Correct

On Jan 29, 2013, at 2:42 PM, James Shaw notifications@github.com wrote:

Thanks Derrick. Just to clarify for me, your input JSON (which isn't under your control) has a mixture of integer and double values for the same field whereas your output JSON (which is under your control) always use doubles?

— Reply to this email directly or view it on GitHub.

carterpage commented 11 years ago

Fixed in #27. Will be released in 1.2.0 this month.

smoosh911 commented 6 years ago

This issue still exists when you use the assertEquals(JSONObject, JSONObject) overload. It will break when comparing JSONArray within this overload. It has a problem converting primitive types such as numbers back and forth. In my situation it will convert 1 to 1.0 sometimes and 1 to 1 other times. For example:

JSONObject response = (JSONObject)JSONParser.parseJSON(responseString);
JSONObject baseline = (JSONObject)JSONParser.parseJSON(baseLineString);
JSONAssert.assertEquals(baseline, response, JSONCompareMode.LENIENT);
downloadpizza commented 1 year ago

@smoosh911 may want to open this as its own issue, I've also run into it but don't have the time to open one right now. If I remember then I will open an issue at some point.