Search code examples
javacollectionsjunitequalshamcrest

Assert collection contains object of custom class, which does not override equals/hashcode


We have a custom class with several fields, for which we cannot override equals/hashcode methods for business domain reasons

Nevertheless, during unit testing we should assert on whether a collection contains an item of this class

List<CustomClass> customObjectList = classUnderTest.methodUnderTest();
//create customObject with fields set to the very same values as one of the elements in customObjectList
//we should assert here that customObjectList contains customObject

However, so far we did not find any solution that would work without overriding equals/hashcode, e.g. Hamcrest

assertThat(customObjectList, contains(customObject));

results in AssertionError citing

Expected: iterable containing [<CustomClass@578486a3>]
but: item 0: was <CustomClass@551aa95a>

Is there a solution to this without having to compare field-by-field?


Solution

  • I would like to say thank you for all the responses, there have been some really good points made

    However, what I forgot to mention in my question, is that our custom classes are recursive, that is containing fields of other custom class types, for which the same restriction applies regarding equals and hashcode overriding. Unfortunately neither of the mentioned out-of-the box solutions (AssertJ, Nitor Creations) seem to support deep comparison

    Nevertheless, there still seems to be a solution, and that is ReflectionAssert class from Unitils. The following seems to work as we expected, even able to ignore element order in the collection

    assertReflectionEquals(Arrays.asList(customObject1, customObject3, customObject2), customObjectList, ReflectionComparatorMode.LENIENT_ORDER);