Skip to content

Retain assertTrue/assertFalse(a.equals(null)) as is - #1075

Merged
timtebeek merged 3 commits into
mainfrom
tim/sao-tome-v1
Aug 5, 2026
Merged

Retain assertTrue/assertFalse(a.equals(null)) as is#1075
timtebeek merged 3 commits into
mainfrom
tim/sao-tome-v1

Conversation

@timtebeek

@timtebeek timtebeek commented Aug 5, 2026

Copy link
Copy Markdown
Member

Three recipes in the JUnit 4 → 5 pipeline conspired to turn assertFalse(a.equals(null)) into assertNotEquals(null, a), which never calls a.equals(null)Assertions.objectsAreEqual short circuits when its first argument is null. Tests written to cover the null contract of a custom equals() then pass unconditionally.

  • AssertTrueEqualsToAssertEquals and AssertFalseEqualsToAssertNotEquals no longer convert when the argument to .equals() is a null literal (also when parenthesized or cast).
  • AssertionsArgumentOrder no longer reorders assertEquals / assertNotEquals arguments when either compared argument is a null literal. Reference assertions such as assertSame are still reordered, as == is symmetric.

That argument flip was added in #492 to keep the AssertJ migration compiling: assertNotEquals(myVariable, null) would otherwise migrate to assertThat(null).isNotEqualTo(myVariable), an ambiguous method call. JUnitAssertEqualsToAssertThat and JUnitAssertNotEqualsToAssertThat now handle that directly by asserting on the non-null argument — assertThat(myVariable).isNotEqualTo(null) — which both compiles and still calls myVariable.equals(null) through AssertJ's Objects.areEqual.

Two existing expectations in CleanupAssertionsTest changed as a result, both now asserting the more conservative outcome:

  • assertFalse(!"".equals(null)) stops at assertTrue("".equals(null)) instead of collapsing to assertNull("").
  • assertNotEquals(myVariable, null) is left as is instead of being flipped.

Converting these to assertEquals/assertNotEquals with a null argument silently
drops the null-contract test, as Assertions.objectsAreEqual short circuits on a
null argument instead of calling a.equals(null).

Fixes #1071
AssertionsArgumentOrder moved a null literal into the expected position,
which short circuits the equality check instead of calling equals. The
argument flip was previously needed to avoid an ambiguous assertThat(null)
call in the AssertJ migration; the JUnit assert(Not)Equals to AssertJ
recipes now assert on the non-null argument instead.

Fixes #1071
@timtebeek
timtebeek marked this pull request as ready for review August 5, 2026 18:54
@timtebeek
timtebeek merged commit fd1f3d8 into main Aug 5, 2026
1 check passed
@timtebeek
timtebeek deleted the tim/sao-tome-v1 branch August 5, 2026 20:25
@github-project-automation github-project-automation Bot moved this from In Progress to Done in OpenRewrite Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

JUnit 4 to 5 migration silently disables equals(null) null-contract tests

1 participant