I want to compare two objects using org.assertj.core.api.Assertions.assertThat
from version 3.14.0
:
assertThat(getActual())
.usingRecursiveComparison()
.ignoringFields("customer", "orders", "\$hashCode", "fragments.parentFields.__typename", "fragments.parentFields.image")
.isEqualTo(orderForm)
When I do so I get the following error:
when recursively comparing field by field, but found the following difference:
field/property 'fragments' differ:
- actual value : Fragments{parentFields=Optional[ParentFields{__typename=OrderForm, id=1, image=Image{__typename=Image, id=71, accuracy=100.0, type=ORDER_FORM, state=AUTOMATIC, value=order form, base64=}}]}
- expected value : Fragments{parentFields=Optional[ParentFields{__typename=ParentFields, id=1, image=Image{__typename=Image, id=123, accuracy=99.99, type=NONE, state=NONE, value=value, base64=base64}}]}
The recursive comparison was performed with this configuration:
- the following fields were ignored in the comparison: customer, orders, $hashCode, fragments.parentFields.__typename, fragments.parentFields.image
- overridden equals methods were used in the comparison
- these types were compared with the following comparators:
- java.lang.Double -> DoubleComparator[precision=1.0E-15]
- java.lang.Float -> FloatComparator[precision=1.0E-6]
- actual and expected objects and their fields were compared field by field recursively even if they were not of the same type, this allows for example to compare a Person to a PersonDto (call strictTypeChecking(true) to change that behavior).
From my understanding, ignoring all the fileds I added to the ignoreingFields
function the comparison should be:
- actual value : Fragments{parentFields=Optional[ParentFields{id=1}]}
- expected value : Fragments{parentFields=Optional[ParentFields{id=1}]}
And thus it should not fail, it should succeed.
The other ignored fileds (customer
, orders
, \$hashCode
) are getting ignored correctly. So I wonder if there is something wrong with fields of nested objects. But in the javadoc I found:
* // assertion succeeds as name and home.address.street fields are ignored in the comparison
* assertThat(sherlock).usingRecursiveComparison()
* .ignoringFields("name", "home.address.street")
* .isEqualTo(noName);
So I think im using it as intended by the API.
Ofcourse I could get around all this by simply doing:
assertThat(actual
?.fragments()
?.parentFields()
?.get()
?.id()
).isEqualTo(orderForm
.fragments()
.parentFields()
.get()
.id())
But I have many objects which I have to compare like that and which do not have the same super class. So im going to create something like:
fun assertCommons(actual: Any, expected: Any) {
assertThat(actual)
.usingRecursiveComparison()
....
}
So back to the question: What goes wrong with ignoring these fields?
EDIT
Since parentFields
is an optional:
...
.ignoringFields("customer", "orders", "\$hashCode", "fragments.parentFields.get().__typename", "fragments.parentFields.get().image")
...
field/property 'fragments' differ:
- actual value : Fragments{parentFields=Optional[ParentFields{__typename=OrderForm, id=1, image=Image{__typename=Image, id=71, accuracy=100.0, type=ORDER_FORM, state=AUTOMATIC, value=order form, base64=}}]}
- expected value : Fragments{parentFields=Optional[ParentFields{__typename=ParentFields, id=1, image=Image{__typename=Image, id=123, accuracy=99.99, type=NONE, state=NONE, value=value, base64=base64}}]}
The recursive comparison was performed with this configuration:
- the following fields were ignored in the comparison: customer, orders, $hashCode, fragments.parentFields.get().__typename, fragments.parentFields.get().image
- overridden equals methods were used in the comparison
- these types were compared with the following comparators:
- java.lang.Double -> DoubleComparator[precision=1.0E-15]
- java.lang.Float -> FloatComparator[precision=1.0E-6]
- actual and expected objects and their fields were compared field by field recursively even if they were not of the same type, this allows for example to compare a Person to a PersonDto (call strictTypeChecking(true) to change that behavior).
With value
instead of get()
...
.ignoringFields("customer", "orders", "\$hashCode", "fragments.parentFields.value.__typename", "fragments.parentFields.value.image")
...
when recursively comparing field by field, but found the following difference:
field/property 'fragments' differ:
- actual value : Fragments{parentFields=Optional[ParentFields{__typename=OrderForm, id=1, image=Image{__typename=Image, id=71, accuracy=100.0, type=ORDER_FORM, state=AUTOMATIC, value=order form, base64=Optional[]}}]}
- expected value : Fragments{parentFields=Optional[ParentFields{__typename=ParentFields, id=1, image=Image{__typename=Image, id=123, accuracy=99.99, type=NONE, state=NONE, value=value, base64=Optional[base64]}}]}
The recursive comparison was performed with this configuration:
- the following fields were ignored in the comparison: customer, orders, $hashCode, fragments.parentFields.value
- overridden equals methods were used in the comparison
- these types were compared with the following comparators:
- java.lang.Double -> DoubleComparator[precision=1.0E-15]
- java.lang.Float -> FloatComparator[precision=1.0E-6]
- actual and expected objects and their fields were compared field by field recursively even if they were not of the same type, this allows for example to compare a Person to a PersonDto (call strictTypeChecking(true) to change that behavior).
"fragments.parentFields.get().__typename"
is not a valid declaration for what you intend to do. when specifying "a.b.c"
what AssertJ it going to do is try finding getA().getB().getC()
or a.b.c
or nay combination of field/getter (like getA().b.getC()
.
Specifying fragments.parentFields.get()
is not going to work as there is no field named get()
. Try using value
instead as this is the field returned by get()
(AssertJ can read private fields).