I've come across an interesting behavior of recursive comparison in assertj library. If you compare objects of classes that are sub-classes, fields of super classes seem to be skipped during the comparison. Is that a known issue? Or am I doing something wrong? Here is a brief example:
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class ExampleTest {
@Test
public void test() {
MyException expected =
new MyException("Expected text message");
MyException actual = new MyException("Actual text message"); //values for the field Throwable.detailMessage are different
assertThat(actual).usingRecursiveComparison().ignoringAllOverriddenEquals().isEqualTo(expected);
}
}
class MyException extends RuntimeException {
MyException(String message) {
super(message);
}
}
This test will pass when actually it should not as actual.getMessage()
and expected.getMessage()
will show different values.
Apparently, the lib skips comparison of the fields that are inherited from superclasses that reside in java.lang
. As MyException
is using a detailMessage
field inherited from java.lang.Throwable
, it is skipped.
Here is the code from org.assertj.core.internal.Objects
that seems to be responsible for such a behavior:
/**
* Returns the declared fields of given class and its superclasses stopping at superclass in <code>java.lang</code>
* package whose fields are not included.
*
* @param clazz the class we want the declared fields.
* @return the declared fields of given class and its superclasses.
*/
public static Set<Field> getDeclaredFieldsIncludingInherited(Class<?> clazz) {
checkNotNull(clazz, "expecting Class parameter not to be null");
Set<Field> declaredFields = getDeclaredFieldsIgnoringSyntheticAndStatic(clazz);
// get fields declared in superclass
Class<?> superclazz = clazz.getSuperclass();
while (superclazz != null && !superclazz.getName().startsWith("java.lang")) {
declaredFields.addAll(getDeclaredFieldsIgnoringSyntheticAndStatic(superclazz));
superclazz = superclazz.getSuperclass();
}
return declaredFields;
}