-
-
Notifications
You must be signed in to change notification settings - Fork 708
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
Recursive comparison with custom comparator throws AssertionError when objects are equal #2954
Comments
Thanks for reporting this @Soamid |
This one is tricky, as you pointed out the cause is how we deal with visited nodes, we compare them without evaluating the field location to be able to track potential cycles. Take for example a To detect visited nodes, we compare them by reference, if we check the node location your test succeeds but the cycle detection does not work anymore, the Your test actually succeeds if we build the datastores object with new instances of private static DataStore createDataStore(boolean reverse) {
DataStore dataStore = new DataStore();
dataStore.store1.addAll(reverse ? list(new Data("987"), new Data("456"), new Data("123"))
: list(new Data("123"), new Data("456"), new Data("987")));
dataStore.store2.addAll(reverse ? list(new Data("987"), new Data("456")) : list(new Data("456"), new Data("987")));
return dataStore;
} Having said that, it would be great to support both your use case and the cycle detection but I'm not sure if this is possible, I need to do think about it more. Comparing unordered collection increases the likeliness of the issue as it requires comparing all elements to all expected elements (cross product) leading to duplicate dual values when both collections share the same elements. |
@Soamid I have found a way to address this issue, basically by caching the diff computed per node so that when the same node is visited again, it returns the diff (this addresses also the potential cycles) |
Oh, that's great. :) Thank you for the investigation! It will be really helpful in my case because I have no control if the objects are copied or only referenced in two places (they are populated by DB framework and I use AssertJ in integration tests to write more complex assertions). Having one object in two collections usually is not a good model design, but that's another story and I have to live with it. :D |
@Soamid It would be great if you could check on your side that this was fixed properly, building assert is fairly straightforward ( The recursive comparison unit tests are a challenge because there is so much to cover, we test individual features on small tests but we can't cover all the possible combination, this is why tests from real projects are super valuable. |
I've checked it today and everything works now, not only on this small example but also in my main project (which is quite complex and I use this assertion in multiple scenarios). I've simply uncommented the assertion and all turned green. Thank you once again and looking forward to the release. :) |
Awesome, appreciate you took the time to test. |
Describe the bug
I needed to combine assertion with a custom comparator and recursive comparison of an unordered collection. At first, it worked like a charm, but in a very specific case, it started to fail. I spent hours debugging it and I think I know what causes that problem. In
RecursiveComparisonDifferenceCalculator#initDualValuesToCompare()
detected dual values are filtered to remove already visited cases. However, theequals()
method ofDualValue
only checksactual
andexpected
values, ignoringfieldLocation
(there is a comment there questioning this btw ;) ). As a result, similar dual values created in different locations (e.g. the same object in different collections) are marked as similar and removed. Then, the collection of differences is empty and thencompareUnorderedIterables()
wrongly assumes it found a match and removes investigated value from its iterator...Test case reproducing the bug
It sounds a bit complicated so I highly recommend seeing the example code below and running it with a debugger. Ofc it's not my real case, just a minimal example to reproduce the problem.
It will throw
AssertionError
with the message:The following expected elements were not matched in the actual List12: [pl.edu.agh.mobint.db.application.statistics.phonenumber.Example$DataStore@7331196b]
. If you remove the custom comparator, the test passes.The text was updated successfully, but these errors were encountered: