While using AbstractObjectAssert's usingComparatorForFields(comparator,"field") when one of the field is null then the comparator isn't used.
package api;
import static org.assertj.core.api.Assertions.assertThat;
import model.Person;
import java.sql.Timestamp;
public class ProblemReproduce {
private ProblemReproduce() {
throw new IllegalAccessError("This is main class. Not meant to be accessed.");
}
public static void main(String...args) {
Person adam = new Person(null);
Person eve = new Person(new Timestamp(3L));
assertThat(adam).usingComparatorForFields((a,b)->0,"dateOfBirth").isEqualToComparingFieldByFieldRecursively(eve);
}
}
package model;
import java.sql.Timestamp;
public class Person {
private Timestamp dateOfBirth;
private Health health;
public Person(Timestamp timestamp) {
dateOfBirth = timestamp;
health = new Health(180,80);
}
public Timestamp getDateOfBirth() {
return dateOfBirth;
}
public Health getBmi() {
return health;
}
}
package model;
/**
* Created by tarun on 4/13/17.
*/
public class Health {
private int height;
private int weight;
private int health;
Health(int height,int weight) {
this.height = height;
this.weight = weight;
this.health = height*weight;
}
public int getHealth() {
return health;
}
public int getHeight() {
return height;
}
public int getWeight() {
return weight;
}
@Override
public String toString() {
return Integer.toString(health);
}
}
Output:
Exception in thread "main" java.lang.AssertionError: Expecting:
<model.Person@7dc5e7b4>
to be equal to:
<model.Person@1ee0005>
when recursively comparing field by field, but found the following difference(s):
Path to difference: <dateOfBirth>
- expected: <1970-01-01 05:30:00.003>
- actual : <null>
at api.ProblemReproduce.main(ProblemReproduce.java:16)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Thanks for taking the time to report this issue.
I will look into it this week end.
I just checked again. This is occurring only when either expected or actual is null not if both are null.
Yeah, field by field comparison is too strict about how it selects the comparator to use, if one of the field is null it wrongly bypasses any registered comparators.
It also expects both fields to have the same type which is also too strict.
Will be fixed in the next release.
Fixed, thanks for the test case and the additional analysis.
When will the update be available in the maven repository?
likely in the next 2/3 weeks depending on how busy I am
Ok