Skip to content

Migrate TestNG Assertion (instance) to AssertJ#1064

Merged
timtebeek merged 8 commits into
openrewrite:mainfrom
juherr:juherr/migrate-testng-assertion-to-assertj
Jul 24, 2026
Merged

Migrate TestNG Assertion (instance) to AssertJ#1064
timtebeek merged 8 commits into
openrewrite:mainfrom
juherr:juherr/migrate-testng-assertion-to-assertj

Conversation

@juherr

@juherr juherr commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

What's changed

Adds TestNgAssertionToAssertJ, wired into the TestNgToAssertj aggregate, to migrate TestNG's hard, instance-based assertion class org.testng.asserts.Assertion to static AssertJ assertThat(...). Because Assertion fails immediately (unlike SoftAssert), it maps to the static assertThat entry point — the same target as org.testng.Assert.

// before
Assertion assertion = new Assertion();
assertion.assertEquals("actual", "expected");   // TestNG order: actual, then expected

// after
assertThat("actual").isEqualTo("expected");      // the now-dead local instance is removed

The recipe

  • Rewrites instance assertion calls to static assertThat(...), scoped by exact receiver type (TypeUtils.isOfClassType(..., "org.testng.asserts.Assertion")), so custom Assertion subclasses are left untouched and it stays disjoint from SoftAssert extends Assertion.
  • A visitBlock pass removes the now-unused local Assertion instance once its calls are rewritten (single-cycle; only when the variable has no remaining references). Fields are left in place.
  • Covered: assertEquals/assertNotEquals (TestNG (actual, expected) order, plus message → .as(...) and floating-point delta → isCloseTo(..., within(...))/isNotCloseTo(...)), assertTrue/assertFalse, assertNull/assertNotNull, assertSame/assertNotSame, assertEqualsNoOrdercontainsExactlyInAnyOrder, and fail(...) → static Assertions.fail(...) (no-arg fail()fail(""), matching JUnitFailToAssertJFail).

Shared helper

Extracts the duplicated isFloatingPointType into a package-private TestNgAsserts and points every caller at it: TestNgAssertEqualsToAssertThat, TestNgAssertNotEqualsToAssertThat, TestNgSoftAssertToAssertJ, and the new recipe.

Test change worth noting

TestNgToAssertJTest#hardAssertionIsNotChanged is removed: it asserted that the aggregate leaves a hard org.testng.asserts.Assertion instance unchanged, which is no longer true now that this recipe migrates it. Its replacement, assertionInstanceMigratedViaAggregate, pins the new behaviour, and customAssertionSubclassIsNotChanged keeps the subclass-is-left-alone guarantee.

Tests cover every overload branch, the dead-local removal (plus retention-when-referenced and field-not-removed), and the fail variants.

@juherr
juherr force-pushed the juherr/migrate-testng-assertion-to-assertj branch from 3f61c49 to c9ec528 Compare July 24, 2026 11:05
@juherr
juherr force-pushed the juherr/migrate-testng-assertion-to-assertj branch from c9ec528 to 010662d Compare July 24, 2026 11:13
@timtebeek
timtebeek self-requested a review July 24, 2026 12:44

@timtebeek timtebeek left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again! With a slight bit of polish I'll merge as soon as CI passes.

@timtebeek
timtebeek merged commit acfa18f into openrewrite:main Jul 24, 2026
1 check passed
@juherr
juherr deleted the juherr/migrate-testng-assertion-to-assertj branch July 24, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants