Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in JSONArray comparison when Customizations are specified #109

Open
accantelliw opened this issue Sep 17, 2018 · 14 comments
Open

Error in JSONArray comparison when Customizations are specified #109

accantelliw opened this issue Sep 17, 2018 · 14 comments

Comments

@accantelliw
Copy link

I'm facing an issue comparing 2 json ignoring the differences for some fields (i.e date fields, like createdAt, updatedAt).

So, here is json1:

{
	"level00": {
		"level01": [{
			"id": "11111111-1111-1111-1111-111111111111",
			"name": "Name01",
			"createdAt": "2018-01-01T11:11:11.111Z",
			"updatedAt": "2018-01-01T11:11:11.111Z",
			"clientApplication": "AAAAA",
			"version": 1,
			"options": null
		},
		{
			"id": "22222222-2222-2222-2222-222222222222",
			"name": "Name02",
			"createdAt": "2018-01-01T11:22:22.222Z",
			"updatedAt": "2018-01-01T11:22:22.222Z",
			"clientApplication": "AAAAA",
			"version": 1,
			"options": null
		}]
	}
}

and here is json2:

{
	"level00": {
		"level01": [{
			"id": "11111111-1111-1111-1111-111111111111",
			"name": "Name01",
			"createdAt": "2018-01-01T11:33:33.333Z",
			"updatedAt": "2018-01-01T11:33:33.333Z",
			"clientApplication": "AAAAA",
			"version": 1,
			"options": null
		},
		{
			"id": "22222222-2222-2222-2222-222222222222",
			"name": "Name02",
			"createdAt": "2018-01-01T11:44:44.444Z",
			"updatedAt": "2018-01-01T11:44:44.444Z",
			"clientApplication": "AAAAA",
			"version": 1,
			"options": null
		}]
	}
}

I'm comparing using the following statement:

JSONAssert.assertEquals(json1, json2,
	new CustomComparator(JSONCompareMode.LENIENT, 
		new Customization("**.updatedAt", (o1, o2) -> {
			return true;
		}), 
		new Customization("**.createdAt", (o1, o2) -> {
			return true;
		})
	)));

So, the expected behaviour is that the assertion should be true - that is, the 2 json should be considered equals.
Instead, the comparison failed with the following exception:

java.lang.AssertionError: level00.level01[createdAt=2018-01-01T11:22:22.222Z]
Expected: a JSON object
     but none found
 ; level00.level01[createdAt=2018-01-01T11:11:11.111Z]
Expected: a JSON object
     but none found
 ; level00.level01[createdAt=2018-01-01T11:33:33.333Z]
Unexpected: a JSON object
 ; level00.level01[createdAt=2018-01-01T11:44:44.444Z]
Unexpected: a JSON object

This behavior is wrong because those 2 json differs only for fields createdAt and updatedAt, which should be excluded because they are defined in the customizations.

@accantelliw
Copy link
Author

Going further with analysis, I figured out that the problem is in the way 2 JsonArray of Objects are internally compared.

The array comparison made by compareJSONArrayOfJsonObjects searches for an unique key on "expected" JSONArray and than it checks that the same is an unique key for "actual" JSONArray.
For the example provided, the choosed key is createdAt which values are unique in both "expected" and "actual" JSONArray.

The further step is that createdAt values are used to compare arrays, and there the comparison fails: the values of createdAt in "expected" array (2018-01-01T11:11:11.111Z, 2018-01-01T11:22:22.222Z) are different from the "actual" array (2018-01-01T11:33:33.333Z, 2018-01-01T11:44:44.444Z).

So, the Customizations provided are basically not taken into account.

@martedesco
Copy link

martedesco commented Jul 10, 2019

I was having the same issue same use case (trying to use Customization to ignore a couple one-to-one comparisons ) and by changing the type from STRICT instead of LENIENT worked for me.

@guptavv-vi
Copy link

Hey!! Was the above issue resolved as I am getting the same issue, unique key is part of ignore customisation but failing because it becomes unique key in JSON array comparison
[Temp workaround:] I have fetched the JSON array element individually and run the comparison again but this is redundant code and not efficient

@jaroslawbanas
Copy link

Hi, I have similar issues:
I trying to compare two complex JSON like
1)
{ "id" : "1" childs [ { "id" :"str1" "dataId" : 190 } ] }

{ "id" : "1" childs [ { "id" :"str1" "dataId" : 2 } ] }

When I have added new Customization(""childs [*].dataId"", (o1, o2) -> true)
Then I got error:

java.lang.AssertionError: childs[dataId=190]
Expected: a JSON object
but none found
; childs[dataId=2]
Unexpected: a JSON object

Any chance to resolve it soon?

@jaroslawbanas
Copy link

I was having the same issue same use case (trying to use Customization to ignore a couple one-to-one comparisons ) and by changing the type from STRICT instead of LENIENT worked for me.

Do you know what is the effects of those change? The whole test can be invalid and not checked correctly JSON if you don't do it intentionally.

@guptavv-vi
Copy link

Making it leinent make the comparison pass even if actual Json has extra nodes as this make the comparison one way expected elements should be there in actual but if actual has more than expected it is not considered a assert fail. It considers the JSON extensible, so depending on your need it may or may not make sense to make it leinent

@mlaksh89
Copy link

Any Update or work around for this issue. I have to compare a big json response by skipping a lot of junk attributes. Does anyone already has a better solution to this problem.

I get error below when I try to skip attribute..

  java.lang.AssertionError: FinancingProducts.FinancingProduct[AdministrationType=1106].TariffCalculations.TariffCalculation[TariffCalculationId=uuidd9de7bef551b46139ac2b69ed72a5d99]

Expected: a JSON object
but none found
; FinancingProducts.FinancingProduct[AdministrationType=1106].TariffCalculations.TariffCalculation[TariffCalculationId=uuid9842a4fe3d824551bf1b4ae486e92f28]
Expected: a JSON object
but none found
; FinancingProducts.FinancingProduct[AdministrationType=1106].TariffCalculations.TariffCalculation[TariffCalculationId=uuidde327ab0109a475199858b3188fcf096]
Expected: a JSON object
but none found
; FinancingProducts.FinancingProduct[AdministrationType=1106].TariffCalculations.TariffCalculation[TariffCalculationId=uuidbf7bce8fcc05475b807590bc9ccab804]
Expected: a JSON object
but none found
; FinancingProducts.FinancingProduct[AdministrationType=1106].TariffCalculations.TariffCalculation[TariffCalculationId=uuid7356d8f07c514ce79198e28ef86924f6]
Unexpected: a JSON object
; FinancingProducts.FinancingProduct[AdministrationType=1106].TariffCalculations.TariffCalculation[TariffCalculationId=uuid2f502d41bf47458d9207e486fefafbcf]
Unexpected: a JSON object
; FinancingProducts.FinancingProduct[AdministrationType=1106].TariffCalculations.TariffCalculation[TariffCalculationId=uuid59c3098613f242c2ac23cd7feffca083]
Unexpected: a JSON object
; FinancingProducts.FinancingProduct[AdministrationType=1106].TariffCalculations.TariffCalculation[TariffCalculationId=uuidbf9be1033fe74c50acf240a77ecde6b1]
Unexpected: a JSON object

@kjetester
Copy link

kjetester commented Feb 27, 2020

I have the same issue, I guess.
I'm trying to compare two JSON-files with such code:

JSONAssert.assertEquals(expected, actual, new CustomComparator(JSONCompareMode.LENIENT, new Customization("title", (o1, o2) -> true)));

And all the time I'm getting errors due to JSON has a different order in their identical objects :-(
Note that I'm using the LENIENT Compare Mode and that fields and other objects inside these objects are 100% identical except their placement order...

Thus, in the AssertionError, I'm having 6 expected but absent objects... and 6 unexpected but present objects

@rohitkrishna094
Copy link

Making it strict worked for me.

@ayeshasilvia
Copy link

I was having the same issue same use case (trying to use Customization to ignore a couple one-to-one comparisons ) and by changing the type from STRICT instead of LENIENT worked for me.

Thank you! It worked for me.

@Kriska
Copy link

Kriska commented Apr 19, 2021

STRICT is not suitable in my case. Is there a official recommendation or fix?

@janimationd
Copy link

janimationd commented Jul 9, 2021

Another version of this method which allows us to specify the path to the field to use as the unique key would work fine for my use case. And FWIW I get this error when I use JSONCompareMode.NON_EXTENSIBLE, which is strict on asserting there aren't extra fields but is lenient on array ordering.

@GooDGreY
Copy link

GooDGreY commented Sep 7, 2023

#177 check it out

@jaroslawbanas
Copy link

Hi Finally I found solution to solve this kind of problem:

https://stackoverflow.com/questions/50919776/ignore-specific-node-within-array-when-comparing-two-json-in-java
But then items must be in same order but works :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests