equals and hashCode are used in the implementation of satisfiesExactlyInAnyOrder (when they definitely aren't needed). This can result in incorrect assertion results.
- assertj core version: 3.25.1
- java version: 17
- test framework version: n/a
- os (if relevant):
Example of the issue:
public class MyTest {
@Test
void shouldPassButFails() {
StringAndInt first = new StringAndInt("X", 1);
StringAndInt second = new StringAndInt("X", 2);
assertThat(List.of(first, second)).satisfiesExactlyInAnyOrder(
stringAndInt -> assertThat(stringAndInt.integer).isEqualTo(2),
stringAndInt -> assertThat(stringAndInt.integer).isEqualTo(1)
);
}
private static final class StringAndInt {
private final String string;
private final int integer;
private StringAndInt(
String string,
int integer
) {
this.string = string;
this.integer = integer;
}
@Override
public int hashCode() {
return string.hashCode();
}
@Override
public boolean equals(Object o) {
return (o instanceof StringAndInt other) && other.string.equals(string);
}
@Override
public String toString() {
return "StringAndInt{" +
"string='" + string + '\'' +
", integer=" + integer +
'}';
}
}
}
This test fails with
Expecting actual:
[StringAndInt{string='X', integer=1}, StringAndInt{string='X', integer=2}]
to satisfy all the consumers in any order.
but should pass.
The problem is that the use of List::remove in the implementation results in the wrong element being removed.
In general we believe there are a number of bugs in assertj due to unnecessary usages of equals and hashCode, and think that the best way to weed them out is to have unit tests using classes where equals and hashCode throw exceptions.
equalsandhashCodeare used in the implementation ofsatisfiesExactlyInAnyOrder(when they definitely aren't needed). This can result in incorrect assertion results.Example of the issue:
This test fails with
but should pass.
The problem is that the use of
List::removein the implementation results in the wrong element being removed.In general we believe there are a number of bugs in assertj due to unnecessary usages of
equalsandhashCode, and think that the best way to weed them out is to have unit tests using classes whereequalsandhashCodethrow exceptions.