Skip to content

Use MethodMatcher, AnnotationMatcher and variable types instead of name strings - #1228

Merged
timtebeek merged 2 commits into
mainfrom
tim/type-aware-matchers
Oct 25, 2026
Merged

timtebeek merged 2 commits into
mainfrom
tim/type-aware-matchers

Conversation

@timtebeek

@timtebeek timtebeek commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Several recipes decided what a call or annotation was by comparing simple names, so a user's own equalTo(..), setUp() or returns(..) method, or a variable that merely shared a name with a mock, could be picked up. This switches those spots to MethodMatcher, AnnotationMatcher and JavaType.Variable comparisons.

Matchers instead of name strings:

  • MigrateJUnitTestCase: setName(String), setUp() and tearDown() are matched on junit.framework.TestCase, which replaces the isTestCaseMethod helper plus name checks. The suite() removal now uses a *..* suite() matcher, so only the no-argument suite() that JUnit 3 calls is removed.
  • AssertToAssertions: the two-argument assertSame/assertNotSame/assertEquals/assertNotEquals check and the assertThat exclusion use MethodMatchers on org.junit.Assert.
  • HamcrestMatcherToJUnit5: each Replacement gets an org.hamcrest..* <name>(..) matcher. This replaces Replacement.valueOf(name.toUpperCase()), which used a caught IllegalArgumentException as control flow.
  • MockitoUtils.getFirstTestMethod matches the JUnit 4, JUnit 5 and TestNG @Test annotations rather than any annotation named Test.
  • WhiteboxToReflectionVisitor matches @java.lang.Override.
  • RemoveTestPrefix, SimplifyTestThrows and TestMethodsShouldBeVoid: the hasJUnit5MethodAnnotation chains use a list of AnnotationMatchers, as TestsShouldNotBePublic does. Each recipe keeps its own annotation set. Meta-annotation matching is left off, so composed annotations are still not picked up and behaviour is unchanged.

Variable and type identity:

  • ArgumentMatchersRewriter only treats anyString, anyInt and the like as JMockit matchers when the field is declared on mockit.Invocations.
  • JMockitBlockRewriter recognises returns(..) with a mockit.Expectations returns(..) matcher, so a mocked method named returns is no longer mistaken for it. The FullVerifications/VerificationsInOrder mock de-duplication compares mocks with SemanticallyEqual instead of by simple name.
  • SetupStatementsRewriter tracks spies as identifiers and compares them with SemanticallyEqual as well. EasyMockVerifyToMockitoVerify compares the verify(..) argument with the expect(..) receiver the same way.
  • For two identifiers SemanticallyEqual requires equal simple names and equal field types. Unattributed identifiers (both field types null) therefore still match by name, as before.

Skipped from the item:

  • ParameterizedRunnerToParameterized "super".equals(..): this checks for the super keyword in a constructor call. A type check cannot tell super(..) from this(..) without comparing against the class's supertype, which would be more code than the keyword check for no gain.
  • ArgumentMatchersRewriter "this".equals(..): this is also a keyword check. Matchers are now identified by type in isJmockitArgumentMatcher.
  • SetupStatementsRewriter.getVariableNames: it detects clashes between local variable names when setup statements move out of the block. Different declarations never share a JavaType.Variable, so names are the correct key there.

Verified with ./gradlew test --tests 'org.openrewrite.java.testing.{jmockit,easymock,hamcrest,cleanup,junit5,mockito,testng}.*' (each package passed as its own --tests filter): 171 classes and 1434 tests, 12 skipped, no failures. This covers the JMockit, EasyMock and JUnit 4-to-5 composite tests.

Fixes item N7 of #1211.

@timtebeek
timtebeek merged commit 1a4ab92 into main Oct 25, 2026
2 checks passed
@timtebeek
timtebeek deleted the tim/type-aware-matchers branch October 25, 2026 13:34
@github-project-automation github-project-automation Bot moved this from In Progress to Done in OpenRewrite Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

1 participant