As suggested by @fd8s0 in https://github.com/joel-costigliola/assertj-core/issues/178
Real life usecase:
I have a case of a very big object (which I'm testing when serialising and de-serialising). In some attribute there's a collection of an object which overrides equals.
A pluggable strategy for how to handle Equals would be ideal. I have JAXB generated classes that I would like to compare so I cannot introduce equals methods into them as the files are generated. Being able to add a custom equals like I am able to do with compare.
@derekbassett can you create an issue for that ? otherwise it will fall off our radar.
@derekbassett quoteing @joel-costigliola from https://github.com/joel-costigliola/assertj-core/issues/734
Does usingComparatorForType and usingComparatorForFields along with isEqualToComparingFieldByField address this concern ? If not what can we add/improve ?
closing this by lack of feedback from @derekbassett but feel free to comment and we will reopen it.
reopened because original issue is clear and does not require feedback by @derekbassett
https://github.com/joel-costigliola/assertj-core/issues/734 was the issue I created for @derekbassett suggestion
Is this feature not implemented yet? Currently doing recursive FieldByField comparison checks if there are customEquals methods, where you'd think it would also check field by field is the customEquals is true.
@Fadelis this will be addressed in #1002, the default will be using equals when overridden, field by field comparison was initially meant to enable comparison for classes where equals was not overridden.
Since #1002 seems to be a rather complicated issue, is there any workaround to force the current implementation of isEqualToComparingFieldByFieldRecursively to never use equals on user-provided classes and always compare fields instead? I tried to work my way through the GitHub discussions and the codebase but did not find a solution, yet. Any help would be much appreciated.
@sebroeder There is currently no way to achieve this with assertj (that I'm aware of). You have to resort to other libraries e.g. commons-lang, see: https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/builder/EqualsBuilder.html#reflectionEquals-java.lang.Object-java.lang.Object-boolean-java.lang.Class-boolean-java.lang.String...-
Edit:
The commons-lang solution does not work for unrelated classes. I believe https://github.com/SQiShER/java-object-diff can be used in this case.
@sebroeder there is no straightforward solution to that at the moment.
One alternative is to register RecursiveFieldByFieldComparator for each type with usingComparatorForType before calling isEqualToComparingFieldByFieldRecursively, there is an example of that in the javadoc. If you don't have too many types that might be acceptable.
I relooked at this issue again. It is confusing that in order to accomplish my goal of overriding what method is called when using isEquals() or any of his friends isEqual...(), I would have to write a Comparator.
Most of the user defined objects I have are not mathematical in nature nor sorted and so I do not think of Comparison or Order when using the framework.
One of the reasons why I adopted using this framework is because of it's intuitive nature. Nine times out of ten if I want something I just use my IDE completion and it exists. I think that speaks volumes about the quality work you and the contributors have done.
I had a look at the implementation and since the handling of custom equals() in DeepDifference.java is isolated to a few lines I tried to introduce a second boolean parameter useCustomEquals to determineDifferences().
The required code changes so far are very minimal. Next I would have to fix some tests that broke because they test the internals. After that I would try to _bubble up_ the additional parameter all the way to assertIsEqualToComparingFieldByFieldRecursively. The idea is to keep the current behaviour and API as is and add the additional parameter through overloading (or a separate method). Do you think this would be a viable solution?
I second the praise for the code quality of this project by the way! It is a joy to work through.
That looks a good approach to me, we maybe should use an enum instead of a boolean for better extensibility
That looks a good approach to me, we maybe should use an enum instead of a boolean for better extensibility.
@joel-costigliola can you clarify for me: does @sebroeder's approach just need someone to implement it or is it not going to be implemented due to the changes coming in #1002?
Most helpful comment
I had a look at the implementation and since the handling of custom
equals()inDeepDifference.javais isolated to a few lines I tried to introduce a second boolean parameteruseCustomEqualstodetermineDifferences().The required code changes so far are very minimal. Next I would have to fix some tests that broke because they test the internals. After that I would try to _bubble up_ the additional parameter all the way to
assertIsEqualToComparingFieldByFieldRecursively. The idea is to keep the current behaviour and API as is and add the additional parameter through overloading (or a separate method). Do you think this would be a viable solution?I second the praise for the code quality of this project by the way! It is a joy to work through.