Invalid refactor from isEqualTo(@Nullable Map) to containsExactlyInAnyOrderElementsOf
Closed this issue · 2 comments
What happened?
I maintain a repo that has a helper method like this:
private static void assertAttributesEqual(
@Nullable Map<String, Map<String, String>> expected, @Nullable Object actual) {
Map<String, Map<String, String>> actualAttrs = (Map<String, Map<String, String>>) actual;
assertThat(actualAttrs).isEqualTo(expected);
}
When assertj-automation comes around it attempts to reword that last statement to this instead:
assertThat(actualAttrs).containsExactlyInAnyOrderEntriesOf(expected);
However this fails at test runtime with this exception:
java.lang.NullPointerException: Cannot invoke "java.util.Map.entrySet()" because "map" is null
at org.assertj.core.api.AbstractMapAssert.toEntries(AbstractMapAssert.java:695)
at org.assertj.core.api.AbstractMapAssert.containsExactlyInAnyOrderEntriesOf(AbstractMapAssert.java:690)
at com.mypackage.MyClass.assertAttributesEqual(MyClass.java:38)
The problem is that if the expected
parameter is null (as is declared via the @Nullable
annotation) then the
What did you want to happen?
For expected values that have been annotated @Nullable
, this refactor should be skipped. Or changed to produce a valid refactor that still passes.
See https://github.com/palantir/assertj-automation/pull/631/files for desired behavior (no change)
I disagree -- when values are expected to be null, we should assertThat(value).isNull();
assertj-automation attempts to make asserts more precise, which is difficult when the original assertion is imprecise, sometimes it will cause tests to fail until they're updated with greater precision.
Fair enough. I ended up rewriting the above assertThat
to this:
// if expected is null then check for null directly. containsExactlyInAnyOrderEntriesOf() fails when given a
// null expected value, and assert-automation refactors continuously try to use that method, so we need to
// branch here to avoid a null pointer exception.
// See https://github.com/palantir/assertj-automation/issues/630
if (expected == null) {
assertThat(actual).isNull();
} else {
assertThat(actualAttrs).containsExactlyInAnyOrderEntriesOf(expected);
}