Skip to content

Commit

Permalink
Add VerifyZeroToNoMoreInteractions for Mockito 2 (#631)
Browse files Browse the repository at this point in the history
* Add `VerifyZeroToNoMoreInteractions` for Mockito 2

* Apply suggestions from code review

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Apply suggestions from code review

* Apply formatter

* Reuse ChangeMethodName, as that also changes the type and additional cases

* Fix casing issue in mockito.yml

---------

Co-authored-by: lingenj <je.lingen@portofrotterdam.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Tim te Beek <tim@moderne.io>
  • Loading branch information
4 people authored Nov 5, 2024
1 parent da61d95 commit 9118a3c
Show file tree
Hide file tree
Showing 3 changed files with 299 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2024 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 org.jspecify.annotations.Nullable;
import org.openrewrite.*;
import org.openrewrite.java.ChangeMethodName;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.MethodMatcher;
import org.openrewrite.java.dependencies.DependencyInsight;
import org.openrewrite.java.search.UsesMethod;
import org.openrewrite.java.tree.J;

import java.util.concurrent.atomic.AtomicBoolean;

public class VerifyZeroToNoMoreInteractions extends ScanningRecipe<AtomicBoolean> {

private static final String VERIFY_ZERO_INTERACTIONS = "org.mockito.Mockito verifyZeroInteractions(..)";
private static final MethodMatcher ASSERT_INSTANCE_OF_MATCHER = new MethodMatcher(VERIFY_ZERO_INTERACTIONS, true);

@Override
public String getDisplayName() {
return "Replace `verifyZeroInteractions() to `verifyNoMoreInteractions()";
}

@Override
public String getDescription() {
return "Replaces `verifyZeroInteractions()` with `verifyNoMoreInteractions()` in Mockito tests when migration when using a Mockito version < 3.x.";
}

@Override
public AtomicBoolean getInitialValue(final ExecutionContext ctx) {
return new AtomicBoolean(false);
}

@Override
public TreeVisitor<?, ExecutionContext> getScanner(AtomicBoolean usingOlderMockito) {
TreeVisitor<?, ExecutionContext> div = new DependencyInsight("org.mockito", "mockito-*", "[1.0,3.0)", null).getVisitor();
return new TreeVisitor<Tree, ExecutionContext>() {
@Override
public @Nullable Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
if (!usingOlderMockito.get() && div.visit(tree, ctx) != tree) {
usingOlderMockito.set(true);
}
return tree;
}
};
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor(AtomicBoolean usingOlderMockito) {
return Preconditions.check(usingOlderMockito.get(),
Preconditions.check(new UsesMethod<>(ASSERT_INSTANCE_OF_MATCHER), new JavaIsoVisitor<ExecutionContext>() {
@Override
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
J.MethodInvocation md = super.visitMethodInvocation(method, ctx);

if (!ASSERT_INSTANCE_OF_MATCHER.matches(md)) {
return md;
}

maybeAddImport("org.mockito.Mockito", "verifyNoMoreInteractions");
maybeRemoveImport("org.mockito.Mockito.verifyZeroInteractions");

ChangeMethodName changeMethodName = new ChangeMethodName(VERIFY_ZERO_INTERACTIONS, "verifyNoMoreInteractions", false, false);
return (J.MethodInvocation) changeMethodName.getVisitor().visitNonNull(md, ctx);
}
})
);
}
}
1 change: 1 addition & 0 deletions src/main/resources/META-INF/rewrite/mockito.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ recipeList:
oldParameterNames:
- mode
- verification
- org.openrewrite.java.testing.mockito.VerifyZeroToNoMoreInteractions
- org.openrewrite.java.ChangeMethodName:
methodPattern: org.mockito.Mockito verifyZeroInteractions(..)
newMethodName: verifyNoInteractions
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
/*
* Copyright 2024 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 org.intellij.lang.annotations.Language;
import org.junit.jupiter.api.Test;
import org.openrewrite.DocumentExample;
import org.openrewrite.InMemoryExecutionContext;
import org.openrewrite.java.JavaParser;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;

import static org.openrewrite.java.Assertions.java;
import static org.openrewrite.maven.Assertions.pomXml;

class VerifyZeroToNoMoreInteractionsTest implements RewriteTest {

@Language("xml")
private static final String POM_XML_WITH_MOCKITO_2 = """
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>bla.bla</groupId>
<artifactId>bla-bla</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.17.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
""";

@Override
public void defaults(RecipeSpec spec) {
spec
.parser(JavaParser.fromJavaVersion()
.classpathFromResources(new InMemoryExecutionContext(), "mockito-core-3", "mockito-junit-jupiter-3"))
.recipe(new VerifyZeroToNoMoreInteractions());
}

@Test
@DocumentExample
void shouldReplaceToNoMoreInteractions() {
//language=java
rewriteRun(
pomXml(POM_XML_WITH_MOCKITO_2),
java(
"""
import static org.mockito.Mockito.verifyZeroInteractions;
class MyTest {
void test() {
verifyZeroInteractions(System.out);
}
}
""",
"""
import static org.mockito.Mockito.verifyNoMoreInteractions;
class MyTest {
void test() {
verifyNoMoreInteractions(System.out);
}
}
"""
)
);
}

@Test
void shouldNotReplaceToNoMoreInteractionsForImportOnly() {
//language=java
rewriteRun(
pomXml(POM_XML_WITH_MOCKITO_2),
java(
"""
import static org.mockito.Mockito.verifyZeroInteractions;
class MyTest {}
"""
)
);
}

@Test
void doesNotConvertAnyOtherMethods() {
rewriteRun(
pomXml(POM_XML_WITH_MOCKITO_2),
// language=java
java(
"""
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.Mock;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.verify;
class MyTest {
@Mock
Object myObject;
void test() {
verifyZeroInteractions(System.out);
verify(myObject);
}
}
""",
"""
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.Mock;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verify;
class MyTest {
@Mock
Object myObject;
void test() {
verifyNoMoreInteractions(System.out);
verify(myObject);
}
}
"""
)
);
}

@Test
void doesConvertNestedMethodInvocations() {
rewriteRun(
pomXml(POM_XML_WITH_MOCKITO_2),
// language=java
java(
"""
import java.util.function.Consumer;
import static org.mockito.Mockito.verifyZeroInteractions;
class MyTest {
void test() {
Runnable f = () -> verifyZeroInteractions(System.out);
f.run();
}
}
""",
"""
import java.util.function.Consumer;
import static org.mockito.Mockito.verifyNoMoreInteractions;
class MyTest {
void test() {
Runnable f = () -> verifyNoMoreInteractions(System.out);
f.run();
}
}
"""
)
);
}

@Test
void shouldNotRunOnNewerMockito3OrHigher() {
rewriteRun(
//language=xml
pomXml(
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>bla.bla</groupId>
<artifactId>bla-bla</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
"""),
//language=java
java(
"""
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.verifyZeroInteractions;
class MyTest {
void test() {
verifyZeroInteractions(System.out);
}
}
"""
)
);
}
}

0 comments on commit 9118a3c

Please sign in to comment.