From fd0eb2d69a26a1d32b10b769644d9ae609937ae1 Mon Sep 17 00:00:00 2001 From: gideon-sunbit Date: Wed, 26 Jun 2024 11:41:10 +0300 Subject: [PATCH] Add a NoMissingTypes Precondition to CleanupMockitoImports (#539) * Add a NoMissingTypes Precondition to CleanupMockitoImports to prevent changes if types are missing * Specifically handle Mockito Kotlin imports --------- Co-authored-by: Tim te Beek --- build.gradle.kts | 1 + .../mockito/CleanupMockitoImports.java | 18 ++++-- .../mockito/CleanupMockitoImportsTest.java | 56 ++++++++++++++----- 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4f3662b82..42276ebba 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -55,6 +55,7 @@ dependencies { testRuntimeOnly("net.datafaker:datafaker:latest.release") { exclude(group = "org.yaml", module = "snakeyaml") } + testRuntimeOnly("org.mockito.kotlin:mockito-kotlin:latest.release") testRuntimeOnly("org.testcontainers:testcontainers:latest.release") testRuntimeOnly("org.testcontainers:nginx:latest.release") diff --git a/src/main/java/org/openrewrite/java/testing/mockito/CleanupMockitoImports.java b/src/main/java/org/openrewrite/java/testing/mockito/CleanupMockitoImports.java index 8f9fcae2e..b8e63c553 100644 --- a/src/main/java/org/openrewrite/java/testing/mockito/CleanupMockitoImports.java +++ b/src/main/java/org/openrewrite/java/testing/mockito/CleanupMockitoImports.java @@ -47,7 +47,9 @@ public String getDescription() { @Override public TreeVisitor getVisitor() { - return Preconditions.check(new UsesType<>("org.mockito.*", false), new CleanupMockitoImportsVisitor()); + return Preconditions.check( + new UsesType<>("org.mockito.*", false), + new CleanupMockitoImportsVisitor()); } private static class CleanupMockitoImportsVisitor extends JavaIsoVisitor { @@ -104,12 +106,18 @@ private static class CleanupMockitoImportsVisitor extends JavaIsoVisitor qualifiedMethods) { J.MethodInvocation mi = super.visitMethodInvocation(method, qualifiedMethods); if (MOCKITO_METHOD_NAMES.contains(mi.getSimpleName()) - && mi.getSelect() != null - && TypeUtils.isAssignableTo("org.mockito.Mockito", mi.getSelect().getType())) { + && mi.getSelect() != null + && TypeUtils.isAssignableTo("org.mockito.Mockito", mi.getSelect().getType())) { qualifiedMethods.add(mi.getSimpleName()); } return mi; diff --git a/src/test/java/org/openrewrite/java/testing/mockito/CleanupMockitoImportsTest.java b/src/test/java/org/openrewrite/java/testing/mockito/CleanupMockitoImportsTest.java index 94ad05d85..cf36f76cb 100755 --- a/src/test/java/org/openrewrite/java/testing/mockito/CleanupMockitoImportsTest.java +++ b/src/test/java/org/openrewrite/java/testing/mockito/CleanupMockitoImportsTest.java @@ -19,10 +19,13 @@ import org.openrewrite.DocumentExample; import org.openrewrite.InMemoryExecutionContext; import org.openrewrite.java.JavaParser; +import org.openrewrite.kotlin.KotlinParser; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; +import org.openrewrite.test.TypeValidation; import static org.openrewrite.java.Assertions.java; +import static org.openrewrite.kotlin.Assertions.kotlin; class CleanupMockitoImportsTest implements RewriteTest { @@ -31,6 +34,7 @@ public void defaults(RecipeSpec spec) { spec .parser(JavaParser.fromJavaVersion() .classpathFromResources(new InMemoryExecutionContext(), "mockito-all-1.10")) + .parser(KotlinParser.builder().classpath("mockito-core", "mockito-kotlin")) .recipe(new CleanupMockitoImports()); } @@ -43,12 +47,12 @@ void removesUnusedMockitoImport() { """ import org.mockito.Mock; import java.util.Arrays; - + public class MyTest {} """, """ import java.util.Arrays; - + public class MyTest {} """ ) @@ -65,7 +69,7 @@ void leavesOtherImportsAlone() { import java.util.Collections; import java.util.HashSet; import java.util.List; - + public class MyTest {} """ ) @@ -85,7 +89,7 @@ void doNotRemoveImportsPossiblyAssociatedWithAnUntypedMockitoMethod() { class MyObjectTest { MyObject myObject; MyMockClass myMock; - + void test() { when(myObject.getSomeField()).thenReturn("testValue"); given(myObject.getSomeField()).willReturn("testValue"); @@ -116,7 +120,7 @@ void doNotRemoveImportsAssociatedWithAnUntypedMockitoMethodMixed() { class MyObjectTest { MyObject myObject; MyMockClass myMock; - + void test() { when(myObject.getSomeField()).thenReturn("testValue"); given(myObject.getSomeField()).willReturn("testValue"); @@ -148,7 +152,7 @@ void doNotRemoveImportsAssociatedWithATypedMockitoMethodMixed() { class MyObjectTest { MyObject myObject; MyMockClass myMock; - + void test() { when(myObject.getSomeField()).thenReturn("testValue"); given(myObject.getSomeField()).willReturn("testValue"); @@ -178,7 +182,7 @@ void doNotRemoveStartImportsPossiblyAssociatedWithAnUntypedMockitoMethod() { class MyObjectTest { MyObject myObject; - + void test() { when(myObject.getSomeField()).thenReturn("testValue"); } @@ -212,7 +216,7 @@ class MyObject { class MyObjectTest { @Mock MyObject myObject; - + void test() { when(myObject.getSomeField()).thenReturn("testValue"); } @@ -226,7 +230,7 @@ void test() { class MyObjectTest { @Mock MyObject myObject; - + void test() { when(myObject.getSomeField()).thenReturn("testValue"); } @@ -243,16 +247,16 @@ void preserveStarImports() { java( """ package mockito.example; - + import java.util.List; - + import static org.mockito.Mockito.*; - + public class MockitoArgumentMatchersTest { static class Foo { boolean bool(String str, int i, Object obj) { return false; } } - + public void usesMatchers() { Foo mockFoo = mock(Foo.class); when(mockFoo.bool(anyString(), anyInt(), any(Object.class))).thenReturn(true); @@ -270,7 +274,7 @@ void removeUnusedStarImports() { java( """ import static org.mockito.Mockito.*; - + public class MockitoArgumentMatchersTest { } """, @@ -281,4 +285,28 @@ public class MockitoArgumentMatchersTest { ) ); } + + @Test + void handleKotlinImportsCorrectly() { + rewriteRun( + //language=kotlin + kotlin( + """ + import org.mockito.kotlin.times + class Foo { + fun bar() { + org.mockito.Mockito.mock(Foo::class.java) + } + } + """, + """ + class Foo { + fun bar() { + org.mockito.Mockito.mock(Foo::class.java) + } + } + """ + ) + ); + } }