Add recipe to replace MockitoTestExecutionListener#924
Merged
steve-aom-elliott merged 5 commits intomainfrom Mar 4, 2026
Merged
Add recipe to replace MockitoTestExecutionListener#924steve-aom-elliott merged 5 commits intomainfrom
steve-aom-elliott merged 5 commits intomainfrom
Conversation
30f5ce0 to
e2cd397
Compare
…ropriate Mockito initialization Adds ReplaceMockitoTestExecutionListener recipe that migrates away from @TestExecutionListeners(MockitoTestExecutionListener.class) to the appropriate Mockito initialization for the test framework in use: - JUnit 5: @ExtendWith(MockitoExtension.class) - JUnit 4: @RunWith(MockitoJUnitRunner.class) when no @RunWith exists - TestNG: MockitoAnnotations.openMocks(this) lifecycle methods Registered in the Mockito1to3Migration composite recipe.
- Update copyrights to 2026 - Skip TestNG migration when MockitoAnnotations.openMocks() is already used - Place field at class top, initMocks before first method, closeMocks at end - Regenerate recipes.csv
e2cd397 to
911e972
Compare
timtebeek
reviewed
Mar 2, 2026
src/main/java/org/openrewrite/java/testing/mockito/ReplaceMockitoTestExecutionListener.java
Outdated
Show resolved
Hide resolved
…nMocks - Replace manual isTestNGType recursion with TypeUtils.isAssignableTo for AbstractTestNGSpringContextTests, properly handling full hierarchy - When openMocks is already present but close() is missing, add @AfterMethod closeMocks and still remove @TestExecutionListeners - When both openMocks and @AfterMethod exist, only remove the annotation
MBoegers
reviewed
Mar 3, 2026
src/main/java/org/openrewrite/java/testing/mockito/ReplaceMockitoTestExecutionListener.java
Show resolved
Hide resolved
src/main/java/org/openrewrite/java/testing/mockito/ReplaceMockitoTestExecutionListener.java
Outdated
Show resolved
Hide resolved
src/main/java/org/openrewrite/java/testing/mockito/ReplaceMockitoTestExecutionListener.java
Outdated
Show resolved
Hide resolved
src/main/java/org/openrewrite/java/testing/mockito/ReplaceMockitoTestExecutionListener.java
Outdated
Show resolved
Hide resolved
src/main/java/org/openrewrite/java/testing/mockito/ReplaceMockitoTestExecutionListener.java
Show resolved
Hide resolved
Replace @Getter with @Value/@EqualsAndHashCode on the recipe class. Replace hasOpenMocksCall() with MethodAccess.Matcher and hasAfterMethodAnnotation() with Annotated.Matcher trait patterns.
timtebeek
approved these changes
Mar 4, 2026
MBoegers
approved these changes
Mar 4, 2026
| } | ||
|
|
||
| // Check compilation unit imports | ||
| J.CompilationUnit cu = getCursor().firstEnclosingOrThrow(J.CompilationUnit.class); |
Collaborator
There was a problem hiding this comment.
We could use FindImports here I think.
Contributor
Author
There was a problem hiding this comment.
Ah just saw these. I'll make another PR quickly
|
|
||
| // Check compilation unit imports | ||
| J.CompilationUnit cu = getCursor().firstEnclosingOrThrow(J.CompilationUnit.class); | ||
| for (J.Import imp : cu.getImports()) { |
Collaborator
There was a problem hiding this comment.
I think we could use 2-3 FindImport here
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ReplaceMockitoTestExecutionListenerrecipe that migrates away from@TestExecutionListeners(MockitoTestExecutionListener.class)to the appropriate Mockito initialization for the test framework in use@ExtendWith(MockitoExtension.class)), JUnit 4 (@RunWith(MockitoJUnitRunner.class)when no@RunWithexists), and TestNG (MockitoAnnotations.openMocks(this)lifecycle methods)Mockito1to3Migrationcomposite recipeTestNG approach
For TestNG classes (where JUnit's
@ExtendWithand@RunWithare not available), the recipe addsMockitoAnnotations.openMocks(this)in a@BeforeMethodlifecycle method with the correspondingclose()in@AfterMethod. This is a direct equivalent of whatMockitoTestExecutionListenerdoes internally:MockitoTestExecutionListenercallsopenMocks()under the hood. Decompiling Spring Boot 3.x shows itsinitMocks()method callsMockitoAnnotations.openMocks(testContext.getTestInstance())and stores the returnedAutoCloseablefor cleanup inafterTestMethod(). The recipe produces the same call sequence.TestNG inherits
@BeforeMethod/@AfterMethodfrom parent classes. When the recipe transforms a base class (e.g.BaseTest extends AbstractTestNGSpringContextTests), subclasses with@Mockfields inherit the lifecycle methods automatically. TestNG executes parent@BeforeMethodbefore child methods, and parent@AfterMethodafter child methods.openMocks(this)in a parent class initializes subclass@Mockfields. In Java,thisalways refers to the actual runtime instance (the subclass), so Mockito's reflection-based field scanning traverses the full class hierarchy and initializes all@Mock-annotated fields regardless of where they are declared.Test plan
recipeCsvGenerateregenerated and validated