diff --git a/src/main/java/org/openrewrite/java/testing/mockito/ReplacePowerMockDependencies.java b/src/main/java/org/openrewrite/java/testing/mockito/ReplacePowerMockDependencies.java
new file mode 100644
index 000000000..74a5ab260
--- /dev/null
+++ b/src/main/java/org/openrewrite/java/testing/mockito/ReplacePowerMockDependencies.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2026 the original author or authors.
+ *
+ * Licensed under the Moderne Source Available License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://docs.moderne.io/licensing/moderne-source-available-license
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.openrewrite.java.testing.mockito;
+
+import lombok.Getter;
+import org.openrewrite.ExecutionContext;
+import org.openrewrite.ScanningRecipe;
+import org.openrewrite.Tree;
+import org.openrewrite.TreeVisitor;
+import org.openrewrite.java.MethodMatcher;
+import org.openrewrite.java.dependencies.ChangeDependency;
+import org.openrewrite.java.marker.JavaProject;
+import org.openrewrite.java.tree.JavaSourceFile;
+import org.openrewrite.java.tree.JavaType;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ReplacePowerMockDependencies extends ScanningRecipe {
+
+ @Getter
+ final String displayName = "Replace PowerMock dependencies with Mockito equivalents";
+
+ @Getter
+ final String description = "Replaces PowerMock API dependencies with `mockito-inline` when `mockStatic()`, " +
+ "`whenNew()`, or `@PrepareForTest` usage is detected, or `mockito-core` otherwise. PowerMock features " +
+ "like static mocking, constructor mocking, and final class mocking require the inline mock maker " +
+ "which is bundled in `mockito-inline` for Mockito 3.x/4.x.";
+
+ static class Accumulator {
+ Map needsInlineMocking = new HashMap<>();
+ }
+
+ @Override
+ public Accumulator getInitialValue(ExecutionContext ctx) {
+ return new Accumulator();
+ }
+
+ private static final String PREPARE_FOR_TEST = "org.powermock.core.classloader.annotations.PrepareForTest";
+
+ @Override
+ public TreeVisitor, ExecutionContext> getScanner(Accumulator acc) {
+ MethodMatcher mockStaticMatcher = new MethodMatcher("org.powermock.api.mockito.PowerMockito mockStatic(..)");
+ MethodMatcher whenNewMatcher = new MethodMatcher("org.powermock.api.mockito.PowerMockito whenNew(..)");
+ return new TreeVisitor() {
+ @Override
+ public Tree preVisit(Tree tree, ExecutionContext ctx) {
+ stopAfterPreVisit();
+ if (tree instanceof JavaSourceFile) {
+ JavaProject project = tree.getMarkers().findFirst(JavaProject.class).orElse(null);
+ if (Boolean.TRUE.equals(acc.needsInlineMocking.get(project))) {
+ return tree;
+ }
+ JavaSourceFile sourceFile = (JavaSourceFile) tree;
+ for (JavaType.Method type : sourceFile.getTypesInUse().getUsedMethods()) {
+ if (mockStaticMatcher.matches(type) || whenNewMatcher.matches(type)) {
+ acc.needsInlineMocking.put(project, true);
+ return tree;
+ }
+ }
+ for (JavaType type : sourceFile.getTypesInUse().getTypesInUse()) {
+ if (type instanceof JavaType.FullyQualified &&
+ PREPARE_FOR_TEST.equals(((JavaType.FullyQualified) type).getFullyQualifiedName())) {
+ acc.needsInlineMocking.put(project, true);
+ return tree;
+ }
+ }
+ }
+ return tree;
+ }
+ };
+ }
+
+ @Override
+ public TreeVisitor, ExecutionContext> getVisitor(Accumulator acc) {
+ return new TreeVisitor() {
+ @Override
+ public Tree preVisit(Tree tree, ExecutionContext ctx) {
+ stopAfterPreVisit();
+ JavaProject project = tree.getMarkers().findFirst(JavaProject.class).orElse(null);
+ String targetArtifact = Boolean.TRUE.equals(acc.needsInlineMocking.get(project))
+ ? "mockito-inline" : "mockito-core";
+ doAfterVisit(new ChangeDependency(
+ "org.powermock", "powermock-api-mockito",
+ "org.mockito", targetArtifact, "3.x",
+ null, null, null).getVisitor());
+ doAfterVisit(new ChangeDependency(
+ "org.powermock", "powermock-api-mockito2",
+ "org.mockito", targetArtifact, "3.x",
+ null, null, null).getVisitor());
+ return tree;
+ }
+ };
+ }
+}
diff --git a/src/main/resources/META-INF/rewrite/powermockito.yml b/src/main/resources/META-INF/rewrite/powermockito.yml
index efa732bb9..3a11b3e8b 100644
--- a/src/main/resources/META-INF/rewrite/powermockito.yml
+++ b/src/main/resources/META-INF/rewrite/powermockito.yml
@@ -25,6 +25,7 @@ tags:
- testing
- mockito
recipeList:
+ - org.openrewrite.java.testing.mockito.ReplacePowerMockDependencies
- org.openrewrite.java.RemoveAnnotation:
annotationPattern: "@org.powermock.core.classloader.annotations.PowerMockIgnore"
- org.openrewrite.java.ChangeMethodTargetToStatic:
@@ -46,20 +47,6 @@ recipeList:
- org.openrewrite.java.testing.mockito.PowerMockitoMockStaticToMockito
- org.openrewrite.java.testing.mockito.PowerMockitoWhenNewToMockito
- org.openrewrite.java.testing.mockito.CleanupPowerMockImports
- # powermock-api-mockito (Mockito 1.x bridge) and powermock-api-mockito2 (Mockito 2.x bridge)
- # are mutually exclusive; a project will only ever have one of them.
- - org.openrewrite.java.dependencies.ChangeDependency:
- oldGroupId: org.powermock
- oldArtifactId: powermock-api-mockito
- newGroupId: org.mockito
- newArtifactId: mockito-core
- newVersion: 3.x
- - org.openrewrite.java.dependencies.ChangeDependency:
- oldGroupId: org.powermock
- oldArtifactId: powermock-api-mockito2
- newGroupId: org.mockito
- newArtifactId: mockito-core
- newVersion: 3.x
- org.openrewrite.java.dependencies.RemoveDependency:
groupId: org.powermock
artifactId: powermock*
diff --git a/src/main/resources/META-INF/rewrite/recipes.csv b/src/main/resources/META-INF/rewrite/recipes.csv
index dbcd63a99..1bf2d84c4 100644
--- a/src/main/resources/META-INF/rewrite/recipes.csv
+++ b/src/main/resources/META-INF/rewrite/recipes.csv
@@ -67,11 +67,11 @@ maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.tes
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.assertj.SimplifyRedundantAssertJChains,Simplify redundant AssertJ assertion chains,Removes redundant AssertJ assertions when chained methods already provide the same or stronger guarantees.,1,AssertJ,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.assertj.SimplifySequencedCollectionAssertions,Simplify AssertJ assertions on SequencedCollection,"Simplify AssertJ assertions on SequencedCollection by using dedicated assertion methods. For example, `assertThat(sequencedCollection.getLast())` can be simplified to `assertThat(sequencedCollection).last()`.",1,AssertJ,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.assertj.SimplifyStreamMapToExtracting,Simplify `assertThat(collection.stream().map(...))` to `assertThat(collection).extracting(...)`,Simplifies AssertJ assertions that use `stream().map()` to extract values from a collection by using the dedicated `extracting()` method instead. This makes the assertion more readable and leverages AssertJ's built-in extraction capabilities.,1,AssertJ,Testing,Java,,,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.assertj.Assertj,AssertJ best practices,Migrates JUnit asserts to AssertJ and applies best practices to assertions.,862,AssertJ,Testing,Java,,,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.assertj.Assertj,AssertJ best practices,Migrates JUnit asserts to AssertJ and applies best practices to assertions.,861,AssertJ,Testing,Java,,,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.assertj.StaticImports,Statically import AssertJ's `assertThat`,Consistently use a static import rather than inlining the `Assertions` class name in tests.,3,AssertJ,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.assertj.SimplifyChainedAssertJAssertions,Simplify AssertJ chained assertions,Replace AssertJ assertions where a method is called on the actual value with a dedicated assertion.,63,AssertJ,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.assertj.SimplifyAssertJAssertions,Shorten AssertJ assertions,Replace AssertJ assertions where a dedicated assertion is available for the same actual value.,9,AssertJ,Testing,Java,,,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.assertj.JUnitToAssertj,Migrate JUnit asserts to AssertJ,"AssertJ provides a rich set of assertions, truly helpful error messages, improves test code readability. Converts assertions from `org.junit.jupiter.api.Assertions` to `org.assertj.core.api.Assertions`. Will convert JUnit 4 to JUnit Jupiter if necessary to match and modify assertions.",316,AssertJ,Testing,Java,,,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.assertj.JUnitToAssertj,Migrate JUnit asserts to AssertJ,"AssertJ provides a rich set of assertions, truly helpful error messages, improves test code readability. Converts assertions from `org.junit.jupiter.api.Assertions` to `org.assertj.core.api.Assertions`. Will convert JUnit 4 to JUnit Jupiter if necessary to match and modify assertions.",315,AssertJ,Testing,Java,,,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.assertj.FestToAssertj,Migrate Fest 2.x to AssertJ,"AssertJ provides a rich set of assertions, truly helpful error messages, improves test code readability. Converts Fest 2.x imports to AssertJ imports.",10,AssertJ,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.cleanup.AssertEqualsBooleanToAssertBoolean,"Replace JUnit `assertEquals(false, )` to `assertFalse()` / `assertTrue()`",Using `assertFalse` or `assertTrue` is simpler and more clear.,1,Cleanup,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.cleanup.AssertEqualsNullToAssertNull,"`assertEquals(a, null)` to `assertNull(a)`",Using `assertNull(a)` is simpler and more clear.,1,Cleanup,Testing,Java,,,Basic building blocks for transforming Java code.,,
@@ -100,7 +100,7 @@ maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.tes
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.dbrider.MigrateDbRiderSpringToDbRiderJUnit5,Migrate rider-spring (JUnit4) to rider-junit5 (JUnit5),This recipe will migrate the necessary dependencies and annotations from DbRider with JUnit4 to JUnit5 in a Spring application.,3,DBRider,Testing,Java,Recipes for [DBRider](https://database-rider.github.io/database-rider/) database testing framework.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.easymock.EasyMockVerifyToMockitoVerify,Replace EasyMock `verify` calls with Mockito `verify` calls,Replace `EasyMock.verify(dependency)` with individual `Mockito.verify(dependency).method()` calls based on expected methods.,1,EasyMock,Testing,Java,Recipes for migrating from [EasyMock](https://easymock.org/) to Mockito.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.easymock.RemoveExtendsEasyMockSupport,Migrate Test classes that extend `org.easymock.EasyMockSupport` to use Mockito,Modify test classes by removing extends EasyMockSupport and replacing EasyMock methods with Mockito equivalents.,1,EasyMock,Testing,Java,Recipes for migrating from [EasyMock](https://easymock.org/) to Mockito.,,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.easymock.EasyMockToMockito,Migrate from EasyMock to Mockito,This recipe will apply changes commonly needed when migrating from EasyMock to Mockito.,163,EasyMock,Testing,Java,Recipes for migrating from [EasyMock](https://easymock.org/) to Mockito.,,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.easymock.EasyMockToMockito,Migrate from EasyMock to Mockito,This recipe will apply changes commonly needed when migrating from EasyMock to Mockito.,161,EasyMock,Testing,Java,Recipes for migrating from [EasyMock](https://easymock.org/) to Mockito.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.hamcrest.AssertThatBooleanToAssertJ,"Migrate Hamcrest `assertThat(boolean, Matcher)` to AssertJ","Replace Hamcrest `assertThat(String, boolean)` with AssertJ `assertThat(boolean).as(String).isTrue()`.",1,Hamcrest,Testing,Java,Recipes for migrating from [Hamcrest](http://hamcrest.org/) matchers to AssertJ.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.hamcrest.HamcrestEveryItemToAssertJ,Migrate Hamcrest `everyItem` to AssertJ,Migrate Hamcrest `everyItem` to AssertJ `allSatisfy` or `hasOnlyElementsOfType`.,1,Hamcrest,Testing,Java,Recipes for migrating from [Hamcrest](http://hamcrest.org/) matchers to AssertJ.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.hamcrest.HamcrestHasItemMatcherToAssertJ,Migrate Hamcrest `hasItem(Matcher)` to AssertJ,Migrate Hamcrest `hasItem(Matcher)` to AssertJ `hasAtLeastOneElementOfType` or `anySatisfy`.,1,Hamcrest,Testing,Java,Recipes for migrating from [Hamcrest](http://hamcrest.org/) matchers to AssertJ.,,Basic building blocks for transforming Java code.,,
@@ -119,7 +119,7 @@ maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.tes
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.jmockit.JMockitAnnotatedArgumentToMockito,Convert JMockit `@Mocked` and `@Injectable` annotated arguments,Convert JMockit `@Mocked` and `@Injectable` annotated arguments into Mockito statements.,1,JMockit,Testing,Java,Recipes for migrating from [JMockit](https://jmockit.github.io/) to Mockito.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.jmockit.JMockitBlockToMockito,"Rewrite JMockit Expectations, NonStrictExpectations, Verifications, VerificationsInOrder, FullVerifications","Rewrites JMockit `Expectations, NonStrictExpectations, Verifications, VerificationsInOrder, FullVerifications` blocks to Mockito statements.",1,JMockit,Testing,Java,Recipes for migrating from [JMockit](https://jmockit.github.io/) to Mockito.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.jmockit.JMockitMockUpToMockito,Rewrite JMockit MockUp to Mockito statements,Rewrites JMockit `MockUp` blocks to Mockito statements. This recipe will not rewrite private methods in MockUp.,1,JMockit,Testing,Java,Recipes for migrating from [JMockit](https://jmockit.github.io/) to Mockito.,,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.jmockit.JMockitToMockito,Migrate from JMockit to Mockito,This recipe will apply changes commonly needed when migrating from JMockit to Mockito.,129,JMockit,Testing,Java,Recipes for migrating from [JMockit](https://jmockit.github.io/) to Mockito.,,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.jmockit.JMockitToMockito,Migrate from JMockit to Mockito,This recipe will apply changes commonly needed when migrating from JMockit to Mockito.,127,JMockit,Testing,Java,Recipes for migrating from [JMockit](https://jmockit.github.io/) to Mockito.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.AddMissingNested,JUnit 5 inner test classes should be annotated with `@Nested`,Adds `@Nested` to inner classes that contain JUnit 5 tests.,1,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.AddMissingTestBeforeAfterAnnotations,"Add missing `@BeforeEach`, `@AfterEach`, `@Test` to overriding methods","Adds `@BeforeEach`, `@AfterEach`, `@Test` to methods overriding superclass methods if the annotations are present on the superclass method.",1,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.AddParameterizedTestAnnotation,Add missing `@ParameterizedTest` annotation when `@ValueSource` is used or replace `@Test` with `@ParameterizedTest`,Add missing `@ParameterizedTest` annotation when `@ValueSource` is used or replace `@Test` with `@ParameterizedTest`.,1,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
@@ -160,13 +160,13 @@ maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.tes
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.UseWiremockExtension,Use wiremock extension,"As of 2.31.0, wiremock [supports JUnit 5](https://wiremock.org/docs/junit-jupiter/) via an extension.",2,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.AddHamcrestJUnitDependency,Add Hamcrest JUnit dependency,Add Hamcrest JUnit dependency only if JUnit 4's `assertThat` or `assumeThat` is used.,1,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.AddJupiterDependencies,Add JUnit Jupiter dependencies,"Adds JUnit Jupiter dependencies to a Maven or Gradle project. JUnit Jupiter can be added either with the artifact `junit-jupiter`, or both of `junit-jupiter-api` and `junit-jupiter-engine`. This adds `junit-jupiter` dependency unless `junit-jupiter-api` or `junit-jupiter-engine` are already present.",1,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.JUnit5BestPractices,JUnit 5 best practices,Applies best practices to tests.,234,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.JUnit5BestPractices,JUnit 5 best practices,Applies best practices to tests.,233,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.StaticImports,Statically import JUnit Jupiter assertions,Always use a static import for assertion methods.,2,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.JUnit4to5Migration,JUnit Jupiter migration from JUnit 4.x,Migrates JUnit 4.x tests to JUnit Jupiter.,166,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.JUnit4to5Migration,JUnit Jupiter migration from JUnit 4.x,Migrates JUnit 4.x tests to JUnit Jupiter.,165,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.ExcludeJUnit4UnlessUsingTestcontainers,"Exclude JUnit 4, unless Testcontainers is used","Excludes JUnit 4, as it ought not to be necessary in a JUnit 5 project, unless Testcontainers is used.",2,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.UseHamcrestAssertThat,Use `MatcherAssert#assertThat(..)`,JUnit 4's `Assert#assertThat(..)` This method was deprecated in JUnit 4 and removed in JUnit Jupiter.,3,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.MigrateAssumptions,Use `Assertions#assume*(..)` and Hamcrest's `MatcherAssume#assume*(..)`,Many of JUnit 4's `Assume#assume(..)` methods have no direct counterpart in JUnit 5 and require Hamcrest JUnit's `MatcherAssume`.,7,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.UseMockitoExtension,Use Mockito JUnit Jupiter extension,Migrate uses of `@RunWith(MockitoJUnitRunner.class)` (and similar annotations) to `@ExtendWith(MockitoExtension.class)`.,56,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.UseMockitoExtension,Use Mockito JUnit Jupiter extension,Migrate uses of `@RunWith(MockitoJUnitRunner.class)` (and similar annotations) to `@ExtendWith(MockitoExtension.class)`.,55,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.IgnoreToDisabled,Use JUnit Jupiter `@Disabled`,Migrates JUnit 4.x `@Ignore` to JUnit Jupiter `@Disabled`.,2,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.ThrowingRunnableToExecutable,Use JUnit Jupiter `Executable`,Migrates JUnit 4.x `ThrowingRunnable` to JUnit Jupiter `Executable`.,2,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit5.MigrateAssertionFailedError,Migrate JUnit 4 assertion failure exceptions to JUnit Jupiter,Replace JUnit 4's `junit.framework.AssertionFailedError` and `org.junit.ComparisonFailure` with JUnit Jupiter's `org.opentest4j.AssertionFailedError`.,3,JUnit Jupiter,Testing,Java,Best practices for JUnit Jupiter tests.,,Basic building blocks for transforming Java code.,,
@@ -183,7 +183,7 @@ maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.tes
- Adjust ranges to use minimum the specified version.",1,Junit6,Testing,Java,,,Basic building blocks for transforming Java code.,"[{""name"":""javaVersion"",""type"":""String"",""displayName"":""JRE version"",""description"":""The minimum JRE version to use for test conditions."",""example"":""17"",""required"":true}]",
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit6.RemoveInterceptDynamicTest,Remove `InvocationInterceptor.interceptDynamicTest`,"JUnit 6 removed the `interceptDynamicTest(Invocation, ExtensionContext)` method from `InvocationInterceptor`. This recipe removes implementations of this deprecated method.",1,Junit6,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.junit6.JUnit5to6Migration,JUnit 6 migration from JUnit 5.x,Migrates JUnit 5.x tests to JUnit 6.x.,39,Junit6,Testing,Java,,,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.AddMockitoExtensionIfAnnotationsUsed,Adds Mockito extensions to Mockito tests,Adds `@ExtendWith(MockitoExtension.class)` to tests using `@Mock` or `@Captor`.,1,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.AddMockitoExtensionIfAnnotationsUsed,Adds Mockito extensions to Mockito tests,Adds `@ExtendWith(MockitoExtension.class)` to JUnit 5 tests or `@RunWith(MockitoJUnitRunner.class)` to JUnit 4 tests using Mockito annotations like `@Mock` or `@Captor`.,1,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.AnyStringToNullable,Replace Mockito 1.x `anyString()` with `nullable(String.class)`,Since Mockito 2.10 `anyString()` no longer matches null values. Use `nullable(Class)` instead.,1,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.CleanupMockitoImports,Cleanup Mockito imports,"Removes unused `org.mockito` import symbols, unless its possible they are associated with method invocations having null or unknown type information.",1,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.CleanupPowerMockImports,Cleanup PowerMock imports,Removes unused `org.powermock` import symbols.,1,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
@@ -200,13 +200,14 @@ maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.tes
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.ReplaceInitMockToOpenMock,Replace `MockitoAnnotations.initMocks(this)` to `MockitoAnnotations.openMocks(this)`,Replace `MockitoAnnotations.initMocks(this)` to `MockitoAnnotations.openMocks(this)` and generate `AutoCloseable` mocks.,1,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.SimplifyMockitoVerifyWhenGiven,"Call to Mockito method ""verify"", ""when"" or ""given"" should be simplified","Fixes Sonar issue `java:S6068`: Call to Mockito method ""verify"", ""when"" or ""given"" should be simplified.",1,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.AnyToNullable,Replace Mockito 1.x `anyString()`/`any()` with `nullable(Class)`,Since Mockito 2.10 `anyString()` and `any()` no longer matches null values. Use `nullable(Class)` instead.,1,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.ReplacePowerMockDependencies,Replace PowerMock dependencies with Mockito equivalents,"Replaces PowerMock API dependencies with `mockito-inline` when `mockStatic()`, `whenNew()`, or `@PrepareForTest` usage is detected, or `mockito-core` otherwise. PowerMock features like static mocking, constructor mocking, and final class mocking require the inline mock maker which is bundled in `mockito-inline` for Mockito 3.x/4.x.",1,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.VerifyZeroToNoMoreInteractions,Replace `verifyZeroInteractions()` with `verifyNoMoreInteractions()`,Replaces `verifyZeroInteractions()` with `verifyNoMoreInteractions()` in Mockito tests when migration when using a Mockito version < 3.x.,1,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.MockitoBestPractices,Mockito best practices,Applies best practices for Mockito tests.,117,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.Mockito1to5Migration,Mockito 5.x upgrade,Upgrade Mockito from 1.x to 5.x.,112,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.Mockito4to5Only,Mockito 4 to 5.x upgrade only,Upgrade Mockito from 4.x to 5.x. Does not include 1.x to 4.x migration.,58,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.Mockito1to4Migration,Mockito 4.x upgrade,Upgrade Mockito from 1.x to 4.x.,53,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.Mockito1to3Migration,Mockito 3.x migration from 1.x,Upgrade Mockito from 1.x to 3.x.,48,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
-maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.ReplacePowerMockito,Replace PowerMock with raw Mockito,PowerMockito with raw Mockito; best executed as part of a Mockito upgrade.,14,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.MockitoBestPractices,Mockito best practices,Applies best practices for Mockito tests.,115,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.Mockito1to5Migration,Mockito 5.x upgrade,Upgrade Mockito from 1.x to 5.x.,110,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.Mockito4to5Only,Mockito 4 to 5.x upgrade only,Upgrade Mockito from 4.x to 5.x. Does not include 1.x to 4.x migration.,57,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.Mockito1to4Migration,Mockito 4.x upgrade,Upgrade Mockito from 1.x to 4.x.,52,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.Mockito1to3Migration,Mockito 3.x migration from 1.x,Upgrade Mockito from 1.x to 3.x.,47,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
+maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.mockito.ReplacePowerMockito,Replace PowerMock with raw Mockito,PowerMockito with raw Mockito; best executed as part of a Mockito upgrade.,13,Mockito,Testing,Java,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.testcontainers.AddTestcontainersAnnotations,Adopt `@Container` and add `@Testcontainers`,Convert Testcontainers `@Rule`/`@ClassRule` to JUnit 5 `@Container` and add `@Testcontainers`.,1,Testcontainers,Testing,Java,Recipes for [Testcontainers](https://testcontainers.com/) integration testing with Docker.,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.testcontainers.ConvertToRawType,Remove parameterized type arguments from a Java class,Convert parameterized types of a specified Java class to their raw types.,1,Testcontainers,Testing,Java,Recipes for [Testcontainers](https://testcontainers.com/) integration testing with Docker.,,Basic building blocks for transforming Java code.,"[{""name"":""fullyQualifiedTypeName"",""type"":""String"",""displayName"":""Fully qualified type name"",""description"":""The fully qualified name of the Java class to convert to its raw type."",""example"":""org.testcontainers.containers.PostgreSQLContainer"",""required"":true}]",
maven,org.openrewrite.recipe:rewrite-testing-frameworks,org.openrewrite.java.testing.testcontainers.ExplicitContainerImage,Add image argument to container constructor,"Set the image to use for a container explicitly if unset, rather than relying on the default image for the container class.",1,Testcontainers,Testing,Java,Recipes for [Testcontainers](https://testcontainers.com/) integration testing with Docker.,,Basic building blocks for transforming Java code.,"[{""name"":""containerClass"",""type"":""String"",""displayName"":""Container class"",""description"":""The fully qualified name of the container class to use."",""example"":""org.testcontainers.containers.NginxContainer"",""required"":true},{""name"":""image"",""type"":""String"",""displayName"":""Image to use"",""description"":""The image to use for the container."",""example"":""nginx:1.9.4"",""required"":true},{""name"":""parseImage"",""type"":""Boolean"",""displayName"":""Parse image"",""description"":""Whether to call `DockerImageName.parse(image)`.""}]",
diff --git a/src/test/java/org/openrewrite/java/testing/mockito/ReplacePowerMockitoIntegrationTest.java b/src/test/java/org/openrewrite/java/testing/mockito/ReplacePowerMockitoIntegrationTest.java
index c7e002ce5..c779016a9 100644
--- a/src/test/java/org/openrewrite/java/testing/mockito/ReplacePowerMockitoIntegrationTest.java
+++ b/src/test/java/org/openrewrite/java/testing/mockito/ReplacePowerMockitoIntegrationTest.java
@@ -29,6 +29,8 @@
import static org.openrewrite.gradle.Assertions.buildGradle;
import static org.openrewrite.gradle.toolingapi.Assertions.withToolingApi;
import static org.openrewrite.java.Assertions.java;
+import static org.openrewrite.java.Assertions.mavenProject;
+import static org.openrewrite.java.Assertions.srcTestJava;
import static org.openrewrite.maven.Assertions.pomXml;
class ReplacePowerMockitoIntegrationTest implements RewriteTest {
@@ -1008,7 +1010,7 @@ void addsMockitoCoreWhenOnlyTransitiveThroughPowerMock() {
mavenCentral()
}
dependencies {
- testImplementation("org.mockito:mockito-core:3.12.4")
+ testImplementation("org.mockito:mockito-inline:3.12.4")
}
"""
),
@@ -1089,6 +1091,480 @@ void testWithCalendar() {
);
}
+ @Test
+ void replacesPowerMockDependencyWithMockitoCoreWhenNoInlineMockingNeeded() {
+ rewriteRun(
+ //language=groovy
+ buildGradle(
+ """
+ plugins {
+ id 'java-library'
+ }
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ testImplementation("org.powermock:powermock-api-mockito:1.6.5")
+ testImplementation("org.powermock:powermock-core:1.6.5")
+ }
+ """,
+ """
+ plugins {
+ id 'java-library'
+ }
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ testImplementation("org.mockito:mockito-core:3.12.4")
+ }
+ """
+ ),
+ //language=xml
+ pomXml(
+ """
+
+ org.example
+ some-project
+ 1.0-SNAPSHOT
+
+
+ org.powermock
+ powermock-api-mockito
+ 1.6.5
+
+
+ org.powermock
+ powermock-core
+ 1.6.5
+
+
+
+ """,
+ """
+
+ org.example
+ some-project
+ 1.0-SNAPSHOT
+
+
+ org.mockito
+ mockito-core
+ 3.12.4
+
+
+
+ """
+ ),
+ //language=java
+ java(
+ """
+ import org.junit.jupiter.api.BeforeEach;
+ import org.powermock.api.mockito.PowerMockito;
+ import java.util.Calendar;
+
+ class MyTest {
+
+ private Calendar calendarMock;
+
+ @BeforeEach
+ void setUp() {
+ calendarMock = PowerMockito.mock(Calendar.class);
+ PowerMockito.doCallRealMethod().when(calendarMock).getTime();
+ }
+ }
+ """,
+ """
+ import org.junit.jupiter.api.BeforeEach;
+ import org.mockito.Mockito;
+ import java.util.Calendar;
+
+ class MyTest {
+
+ private Calendar calendarMock;
+
+ @BeforeEach
+ void setUp() {
+ calendarMock = Mockito.mock(Calendar.class);
+ Mockito.doCallRealMethod().when(calendarMock).getTime();
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void replacesPowerMockDependencyWithMockitoInlineWhenMockStaticDetected() {
+ rewriteRun(
+ //language=groovy
+ buildGradle(
+ """
+ plugins {
+ id 'java-library'
+ }
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ testImplementation("org.powermock:powermock-api-mockito:1.6.5")
+ testImplementation("org.powermock:powermock-core:1.6.5")
+ }
+ """,
+ """
+ plugins {
+ id 'java-library'
+ }
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ testImplementation("org.mockito:mockito-inline:3.12.4")
+ }
+ """
+ ),
+ //language=xml
+ pomXml(
+ """
+
+ org.example
+ some-project
+ 1.0-SNAPSHOT
+
+
+ org.powermock
+ powermock-api-mockito
+ 1.6.5
+
+
+ org.powermock
+ powermock-core
+ 1.6.5
+
+
+
+ """,
+ """
+
+ org.example
+ some-project
+ 1.0-SNAPSHOT
+
+
+ org.mockito
+ mockito-inline
+ 3.12.4
+
+
+
+ """
+ ),
+ //language=java
+ java(
+ """
+ import static org.testng.Assert.assertNotNull;
+
+ import java.util.Calendar;
+
+ import org.powermock.api.mockito.PowerMockito;
+ import org.powermock.core.classloader.annotations.PrepareForTest;
+ import org.testng.annotations.BeforeMethod;
+ import org.testng.annotations.Test;
+
+ @PrepareForTest(value = {Calendar.class})
+ class StaticMethodTest {
+
+ @BeforeMethod
+ void setUp() {
+ PowerMockito.mockStatic(Calendar.class);
+ }
+
+ @Test
+ void testWithCalendar() {
+ assertNotNull(Calendar.getInstance());
+ }
+ }
+ """,
+ """
+ import static org.testng.Assert.assertNotNull;
+
+ import java.util.Calendar;
+
+ import org.mockito.MockedStatic;
+ import org.mockito.Mockito;
+ import org.testng.annotations.AfterMethod;
+ import org.testng.annotations.BeforeMethod;
+ import org.testng.annotations.Test;
+
+ class StaticMethodTest {
+
+ private MockedStatic mockedCalendar;
+
+ @BeforeMethod
+ void setUp() {
+ mockedCalendar = Mockito.mockStatic(Calendar.class);
+ }
+
+ @AfterMethod(alwaysRun = true)
+ void tearDownStaticMocks() {
+ mockedCalendar.closeOnDemand();
+ }
+
+ @Test
+ void testWithCalendar() {
+ assertNotNull(Calendar.getInstance());
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void replacesPowerMockDependencyWithMockitoInlineWhenWhenNewDetected() {
+ rewriteRun(
+ //language=groovy
+ buildGradle(
+ """
+ plugins {
+ id 'java-library'
+ }
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ testImplementation("org.powermock:powermock-api-mockito:1.6.5")
+ testImplementation("org.powermock:powermock-core:1.6.5")
+ }
+ """,
+ """
+ plugins {
+ id 'java-library'
+ }
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ testImplementation("org.mockito:mockito-inline:3.12.4")
+ }
+ """
+ ),
+ //language=xml
+ pomXml(
+ """
+
+ org.example
+ some-project
+ 1.0-SNAPSHOT
+
+
+ org.powermock
+ powermock-api-mockito
+ 1.6.5
+
+
+ org.powermock
+ powermock-core
+ 1.6.5
+
+
+
+ """,
+ """
+
+ org.example
+ some-project
+ 1.0-SNAPSHOT
+
+
+ org.mockito
+ mockito-inline
+ 3.12.4
+
+
+
+ """
+ ),
+ //language=java
+ java(
+ """
+ import org.powermock.api.mockito.PowerMockito;
+ import static org.powermock.api.mockito.PowerMockito.*;
+
+ import org.junit.jupiter.api.Test;
+ import static org.junit.jupiter.api.Assertions.assertEquals;
+
+ class MyTest {
+ static class Generator {
+ public int getLuckyNumber() {
+ return 436;
+ }
+ }
+ @Test
+ void testNumbers() throws Exception {
+ Generator mock = mock(Generator.class);
+ PowerMockito.whenNew(Generator.class).withNoArguments().thenReturn(mock);
+
+ Generator gen = new Generator();
+ when(gen.getLuckyNumber()).thenReturn(504);
+
+ assertEquals(504, gen.getLuckyNumber());
+ }
+ }
+ """,
+ """
+ import static org.mockito.Mockito.when;
+ import static org.mockito.Mockito.mock;
+
+ import org.junit.jupiter.api.Test;
+ import org.mockito.MockedConstruction;
+ import org.mockito.Mockito;
+
+ import static org.junit.jupiter.api.Assertions.assertEquals;
+
+ class MyTest {
+ static class Generator {
+ public int getLuckyNumber() {
+ return 436;
+ }
+ }
+
+ @Test
+ void testNumbers() throws Exception {
+ try (MockedConstruction mockGenerator = Mockito.mockConstruction(Generator.class)) {
+
+ Generator gen = new Generator();
+ when(gen.getLuckyNumber()).thenReturn(504);
+
+ assertEquals(504, gen.getLuckyNumber());
+ }
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void replacesPowerMockDependencyWithMockitoInlineWhenPrepareForTestDetected() {
+ rewriteRun(
+ //language=groovy
+ buildGradle(
+ """
+ plugins {
+ id 'java-library'
+ }
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ testImplementation("org.powermock:powermock-api-mockito:1.6.5")
+ testImplementation("org.powermock:powermock-core:1.6.5")
+ }
+ """,
+ """
+ plugins {
+ id 'java-library'
+ }
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ testImplementation("org.mockito:mockito-inline:3.12.4")
+ }
+ """
+ ),
+ //language=xml
+ pomXml(
+ """
+
+ org.example
+ some-project
+ 1.0-SNAPSHOT
+
+
+ org.powermock
+ powermock-api-mockito
+ 1.6.5
+
+
+ org.powermock
+ powermock-core
+ 1.6.5
+
+
+
+ """,
+ """
+
+ org.example
+ some-project
+ 1.0-SNAPSHOT
+
+
+ org.mockito
+ mockito-inline
+ 3.12.4
+
+
+
+ """
+ ),
+ //language=java
+ java(
+ """
+ import org.powermock.api.mockito.PowerMockito;
+ import org.powermock.core.classloader.annotations.PrepareForTest;
+ import org.junit.jupiter.api.BeforeEach;
+ import org.junit.jupiter.api.Test;
+ import static org.junit.jupiter.api.Assertions.assertNotNull;
+ import java.util.Calendar;
+
+ @PrepareForTest(Calendar.class)
+ class MyTest {
+ Calendar mock;
+
+ @BeforeEach
+ void setUp() {
+ mock = PowerMockito.mock(Calendar.class);
+ }
+
+ @Test
+ void testFinalClass() {
+ assertNotNull(mock);
+ }
+ }
+ """,
+ """
+ import org.mockito.Mockito;
+ import org.junit.jupiter.api.AfterEach;
+ import org.junit.jupiter.api.BeforeEach;
+ import org.junit.jupiter.api.Test;
+ import static org.junit.jupiter.api.Assertions.assertNotNull;
+ import java.util.Calendar;
+
+ class MyTest {
+ Calendar mock;
+
+ @BeforeEach
+ void setUp() {
+ mock = Mockito.mock(Calendar.class);
+ }
+
+ @AfterEach
+ void tearDownStaticMocks() {
+ }
+
+ @Test
+ void testFinalClass() {
+ assertNotNull(mock);
+ }
+ }
+ """
+ )
+ );
+ }
+
@Test
void removesAllPowerMockDependencies() {
rewriteRun(
@@ -1164,6 +1640,128 @@ void removesAllPowerMockDependencies() {
);
}
+ @Test
+ void multiModuleProjectGetsCorrectDependencyPerModule() {
+ rewriteRun(
+ spec -> spec.recipe(new ReplacePowerMockDependencies()),
+ mavenProject("module-a",
+ //language=xml
+ pomXml(
+ """
+
+ org.example
+ module-a
+ 1.0-SNAPSHOT
+
+
+ org.powermock
+ powermock-api-mockito
+ 1.6.5
+
+
+
+ """,
+ """
+
+ org.example
+ module-a
+ 1.0-SNAPSHOT
+
+
+ org.mockito
+ mockito-inline
+ 3.12.4
+
+
+
+ """
+ ),
+ srcTestJava(
+ //language=java
+ java(
+ """
+ import org.powermock.api.mockito.PowerMockito;
+ import java.util.Calendar;
+
+ class StaticMockTest {
+ void test() {
+ PowerMockito.mockStatic(Calendar.class);
+ }
+ }
+ """
+ )
+ )
+ ),
+ mavenProject("module-b",
+ //language=xml
+ pomXml(
+ """
+
+ org.example
+ module-b
+ 1.0-SNAPSHOT
+
+
+ org.powermock
+ powermock-api-mockito
+ 1.6.5
+
+
+
+ """,
+ """
+
+ org.example
+ module-b
+ 1.0-SNAPSHOT
+
+
+ org.mockito
+ mockito-core
+ 3.12.4
+
+
+
+ """
+ ),
+ srcTestJava(
+ //language=java
+ java(
+ """
+ import org.powermock.api.mockito.PowerMockito;
+ import java.util.Calendar;
+
+ class RegularMockTest {
+ void test() {
+ Calendar mock = PowerMockito.mock(Calendar.class);
+ }
+ }
+ """
+ )
+ )
+ ),
+ mavenProject("module-c",
+ //language=xml
+ pomXml(
+ """
+
+ org.example
+ module-c
+ 1.0-SNAPSHOT
+
+
+ junit
+ junit
+ 4.13.2
+
+
+
+ """
+ )
+ )
+ );
+ }
+
@Test
void removesManagedPowerMockDependencies() {
rewriteRun(