From 2d0ae1033af73ee7608e76c660553806788727a5 Mon Sep 17 00:00:00 2001 From: Shivani Sharma Date: Mon, 14 Oct 2024 01:58:54 +1100 Subject: [PATCH 1/9] Migrate JMockit FullVerifications to Mockito --- .../testing/jmockit/JMockitBlockRewriter.java | 50 +++- .../jmockit/JMockitBlockToMockito.java | 17 +- .../testing/jmockit/JMockitBlockType.java | 16 +- ...JMockitFullVerificationsToMockitoTest.java | 246 ++++++++++++++++++ 4 files changed, 309 insertions(+), 20 deletions(-) create mode 100644 src/test/java/org/openrewrite/java/testing/jmockit/JMockitFullVerificationsToMockitoTest.java diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java index 4dc1df56f..57a1574b7 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java @@ -29,13 +29,14 @@ import java.util.ArrayList; import java.util.List; +import static org.openrewrite.java.testing.jmockit.JMockitBlockType.FullVerifications; import static org.openrewrite.java.testing.jmockit.JMockitBlockType.NonStrictExpectations; -import static org.openrewrite.java.testing.jmockit.JMockitBlockType.Verifications; class JMockitBlockRewriter { private static final String WHEN_TEMPLATE_PREFIX = "when(#{any()})."; private static final String VERIFY_TEMPLATE_PREFIX = "verify(#{any()}"; + private static final String VERIFY_NO_INTERACTIONS_TEMPLATE_PREFIX = "verifyNoMoreInteractions("; private static final String LENIENT_TEMPLATE_PREFIX = "lenient()."; private static final String RETURN_TEMPLATE_PREFIX = "thenReturn("; @@ -95,14 +96,21 @@ J.Block rewriteMethodBody() { // iterate over the statements and build a list of grouped method invocations and related statements eg times List> methodInvocationsToRewrite = new ArrayList<>(); + List mocks = new ArrayList<>(); int methodInvocationIdx = -1; for (Statement jmockitBlockStatement : jmockitBlock.getStatements()) { if (jmockitBlockStatement instanceof J.MethodInvocation) { - // ensure it's not a returns statement, we add that later to related statements J.MethodInvocation invocation = (J.MethodInvocation) jmockitBlockStatement; - if (invocation.getSelect() != null && !invocation.getName().getSimpleName().equals("returns")) { - methodInvocationIdx++; - methodInvocationsToRewrite.add(new ArrayList<>()); + J.Identifier object = (J.Identifier) invocation.getSelect(); + if (object != null) { + // ensure it's not a returns statement, we add that later to related statements + if (!invocation.getName().getSimpleName().equals("returns")) { + methodInvocationIdx++; + methodInvocationsToRewrite.add(new ArrayList<>()); + } + if (mocks.stream().noneMatch(mock -> mock.getType().equals(object.getType()) && mock.getSimpleName().equals(object.getSimpleName()))) { + mocks.add(object); + } } } @@ -118,6 +126,10 @@ J.Block rewriteMethodBody() { // now rewrite methodInvocationsToRewrite.forEach(this::rewriteMethodInvocation); + + if (blockType == FullVerifications) { + rewriteFullVerifications(new ArrayList<>(mocks)); + } return methodBody; } @@ -136,7 +148,7 @@ private void rewriteMethodInvocation(List statementsToRewrite) { rewriteResult(invocation, mockInvocationResults.getResults(), hasTimes); } - if (!hasResults && !hasTimes && (this.blockType == JMockitBlockType.Expectations || this.blockType == Verifications)) { + if (!hasResults && !hasTimes && (this.blockType == JMockitBlockType.Expectations || this.blockType.isVerifications())) { rewriteVerify(invocation, null, ""); return; } @@ -171,7 +183,7 @@ private void rewriteResult(J.MethodInvocation invocation, List resul List templateParams = new ArrayList<>(); templateParams.add(invocation); templateParams.addAll(results); - this.rewriteFailed = !rewriteTemplate(template, templateParams, nextStatementCoordinates); + rewriteTemplate(template, templateParams, nextStatementCoordinates); if (this.rewriteFailed) { return; } @@ -199,19 +211,19 @@ private void rewriteVerify(J.MethodInvocation invocation, @Nullable Expression t templateParams.add(invocation.getName().getSimpleName()); String verifyTemplate = getVerifyTemplate(invocation.getArguments(), verificationMode, templateParams); JavaCoordinates verifyCoordinates; - if (this.blockType == Verifications) { + if (this.blockType.isVerifications()) { // for Verifications, replace the Verifications block verifyCoordinates = nextStatementCoordinates; } else { // for Expectations put the verify at the end of the method verifyCoordinates = methodBody.getCoordinates().lastStatement(); } - this.rewriteFailed = !rewriteTemplate(verifyTemplate, templateParams, verifyCoordinates); + rewriteTemplate(verifyTemplate, templateParams, verifyCoordinates); if (this.rewriteFailed) { return; } - if (this.blockType == Verifications) { + if (this.blockType.isVerifications()) { setNextStatementCoordinates(++numStatementsAdded); // for Expectations, verify statements added to end of method } @@ -223,6 +235,20 @@ private void rewriteVerify(J.MethodInvocation invocation, @Nullable Expression t } } + private void rewriteFullVerifications(List mocks) { + StringBuilder sb = new StringBuilder(VERIFY_NO_INTERACTIONS_TEMPLATE_PREFIX); + for (int i = 0; i < mocks.size(); i++) { + sb.append(ANY_TEMPLATE_FIELD).append(","); // verifyNoMoreInteractions(mock1, mock2 ... + } + sb.deleteCharAt(sb.length() - 1); + sb.append(")"); + rewriteTemplate(sb.toString(), mocks, nextStatementCoordinates); + if (!this.rewriteFailed) { + setNextStatementCoordinates(++numStatementsAdded); + visitor.maybeAddImport(MOCKITO_IMPORT_FQN_PREFX, "verifyNoMoreInteractions", false); + } + } + private void setNextStatementCoordinates(int numStatementsAdded) { if (numStatementsAdded <= 0 && bodyStatementIndex == 0) { nextStatementCoordinates = methodBody.getCoordinates().firstStatement(); @@ -240,7 +266,7 @@ private void setNextStatementCoordinates(int numStatementsAdded) { this.nextStatementCoordinates = this.methodBody.getStatements().get(lastStatementIdx).getCoordinates().after(); } - private boolean rewriteTemplate(String template, List templateParams, JavaCoordinates + private void rewriteTemplate(String template, List templateParams, JavaCoordinates rewriteCoords) { int numStatementsBefore = methodBody.getStatements().size(); methodBody = JavaTemplate.builder(template) @@ -252,7 +278,7 @@ private boolean rewriteTemplate(String template, List templateParams, Ja rewriteCoords, templateParams.toArray() ); - return methodBody.getStatements().size() > numStatementsBefore; + this.rewriteFailed = methodBody.getStatements().size() <= numStatementsBefore; } private @Nullable String getWhenTemplate(List results, boolean lenient) { diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockToMockito.java b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockToMockito.java index 04db84952..1a41ddc4b 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockToMockito.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockToMockito.java @@ -26,31 +26,34 @@ import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.Statement; +import java.util.Arrays; import java.util.List; import java.util.Optional; -import static org.openrewrite.java.testing.jmockit.JMockitBlockType.*; +import static org.openrewrite.java.testing.jmockit.JMockitBlockType.getSupportedTypesStr; +import static org.openrewrite.java.testing.jmockit.JMockitBlockType.values; @Value @EqualsAndHashCode(callSuper = false) public class JMockitBlockToMockito extends Recipe { + private static final String SUPPORTED_TYPES = getSupportedTypesStr(); + @Override public String getDisplayName() { - return "Rewrite JMockit Expectations, Verifications and NonStrictExpectations"; + return "Rewrite JMockit " + SUPPORTED_TYPES; } @Override public String getDescription() { - return "Rewrites JMockit `Expectations, Verifications and NonStrictExpectations` blocks to Mockito statements."; + return "Rewrites JMockit `" + SUPPORTED_TYPES + "` blocks to Mockito statements."; } @Override public TreeVisitor getVisitor() { - return Preconditions.check(Preconditions.or( - new UsesType<>(Expectations.getFqn(), false), - new UsesType<>(Verifications.getFqn(), false), - new UsesType<>(NonStrictExpectations.getFqn(), false)), new RewriteJMockitBlockVisitor()); + @SuppressWarnings("rawtypes") + UsesType[] usesTypes = Arrays.stream(values()).map(blockType -> new UsesType<>(blockType.getFqn(), false)).toArray(UsesType[]::new); + return Preconditions.check(Preconditions.or(usesTypes), new RewriteJMockitBlockVisitor()); } private static class RewriteJMockitBlockVisitor extends JavaIsoVisitor { diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java index b36c9240f..30cd0958f 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java @@ -17,16 +17,30 @@ import lombok.Getter; +import java.util.Arrays; + @Getter enum JMockitBlockType { Expectations, + NonStrictExpectations, Verifications, - NonStrictExpectations; + FullVerifications; private final String fqn; JMockitBlockType() { this.fqn = "mockit." + this.name(); } + + public boolean isVerifications() { + String blockType = this.name(); + return blockType.equals(Verifications.name()) || blockType.equals(FullVerifications.name()); + } + + public static String getSupportedTypesStr() { + StringBuilder sb = new StringBuilder(); + Arrays.stream(values()).forEach(value -> sb.append(value).append(", ")); + return sb.substring(0, sb.length() - 2); + } } diff --git a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitFullVerificationsToMockitoTest.java b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitFullVerificationsToMockitoTest.java new file mode 100644 index 000000000..dfdc0303e --- /dev/null +++ b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitFullVerificationsToMockitoTest.java @@ -0,0 +1,246 @@ +/* + * Copyright 2023 the original author or authors. + *

+ * 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 + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.jmockit; + +import org.junit.jupiter.api.Test; +import org.openrewrite.DocumentExample; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.Assertions.java; +import static org.openrewrite.java.testing.jmockit.JMockitTestUtils.setDefaultParserSettings; + +/** + * Not doing comprehensive testing as it is covered in JMockitVerificationsToMockitoTest and shares same code path + */ +class JMockitFullVerificationsToMockitoTest implements RewriteTest { + @Override + public void defaults(RecipeSpec spec) { + setDefaultParserSettings(spec); + } + + @DocumentExample + @Test + void whenTimes() { + //language=java + rewriteRun( + java( + """ + import mockit.FullVerifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + myObject.wait(10L, 10); + myObject.wait(10L, 10); + new FullVerifications() {{ + myObject.wait(anyLong, anyInt); + times = 2; + }}; + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.*; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + myObject.wait(10L, 10); + myObject.wait(10L, 10); + verify(myObject, times(2)).wait(anyLong(), anyInt()); + verifyNoMoreInteractions(myObject); + } + } + """ + ) + ); + } + + @DocumentExample + @Test + void whenOtherStatements() { + //language=java + rewriteRun( + java( + """ + import mockit.FullVerifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + myObject.wait(10L, 10); + new FullVerifications() {{ + myObject.wait(anyLong, anyInt); + }}; + System.out.println("bla"); + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.*; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + myObject.wait(10L, 10); + verify(myObject).wait(anyLong(), anyInt()); + verifyNoMoreInteractions(myObject); + System.out.println("bla"); + } + } + """ + ) + ); + } + + @Test + void whenMultipleMocks() { + //language=java + rewriteRun( + java( + """ + import mockit.FullVerifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + @Mocked + String str; + + void test() { + myObject.wait(10L, 10); + myObject.wait(10L, 10); + str.notify(); + new FullVerifications() {{ + myObject.wait(anyLong, anyInt); + times = 2; + str.notify(); + }}; + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.*; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + @Mock + String str; + + void test() { + myObject.wait(10L, 10); + myObject.wait(10L, 10); + str.notify(); + verify(myObject, times(2)).wait(anyLong(), anyInt()); + verify(str).notify(); + verifyNoMoreInteractions(myObject, str); + } + } + """ + ) + ); + } + + @Test + void whenMultipleInvocationsSameMock() { + //language=java + rewriteRun( + java( + """ + import mockit.FullVerifications; + import mockit.Mocked; + import mockit.integration.junit5.JMockitExtension; + import org.junit.jupiter.api.extension.ExtendWith; + + @ExtendWith(JMockitExtension.class) + class MyTest { + @Mocked + Object myObject; + + void test() { + myObject.wait(10L, 10); + myObject.wait(); + new FullVerifications() {{ + myObject.wait(anyLong, anyInt); + myObject.wait(); + }}; + } + } + """, + """ + import org.junit.jupiter.api.extension.ExtendWith; + import org.mockito.Mock; + import org.mockito.junit.jupiter.MockitoExtension; + + import static org.mockito.Mockito.*; + + @ExtendWith(MockitoExtension.class) + class MyTest { + @Mock + Object myObject; + + void test() { + myObject.wait(10L, 10); + myObject.wait(); + verify(myObject).wait(anyLong(), anyInt()); + verify(myObject).wait(); + verifyNoMoreInteractions(myObject); + } + } + """ + ) + ); + } +} From a98431e9bf798fe537243f6742411ac8630dcebf Mon Sep 17 00:00:00 2001 From: Shivani Sharma Date: Mon, 14 Oct 2024 02:06:18 +1100 Subject: [PATCH 2/9] Clean up full verifications migration --- .../testing/jmockit/JMockitBlockRewriter.java | 8 ++-- .../testing/jmockit/JMockitBlockType.java | 4 +- ...JMockitFullVerificationsToMockitoTest.java | 48 +++++++++---------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java index 57a1574b7..e6a023e0e 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java @@ -96,7 +96,7 @@ J.Block rewriteMethodBody() { // iterate over the statements and build a list of grouped method invocations and related statements eg times List> methodInvocationsToRewrite = new ArrayList<>(); - List mocks = new ArrayList<>(); + List uniqueMocks = new ArrayList<>(); int methodInvocationIdx = -1; for (Statement jmockitBlockStatement : jmockitBlock.getStatements()) { if (jmockitBlockStatement instanceof J.MethodInvocation) { @@ -108,8 +108,8 @@ J.Block rewriteMethodBody() { methodInvocationIdx++; methodInvocationsToRewrite.add(new ArrayList<>()); } - if (mocks.stream().noneMatch(mock -> mock.getType().equals(object.getType()) && mock.getSimpleName().equals(object.getSimpleName()))) { - mocks.add(object); + if (uniqueMocks.stream().noneMatch(mock -> mock.getType().equals(object.getType()) && mock.getSimpleName().equals(object.getSimpleName()))) { + uniqueMocks.add(object); } } } @@ -128,7 +128,7 @@ J.Block rewriteMethodBody() { methodInvocationsToRewrite.forEach(this::rewriteMethodInvocation); if (blockType == FullVerifications) { - rewriteFullVerifications(new ArrayList<>(mocks)); + rewriteFullVerifications(new ArrayList<>(uniqueMocks)); } return methodBody; } diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java index 30cd0958f..19e2fa4f9 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java @@ -33,12 +33,12 @@ enum JMockitBlockType { this.fqn = "mockit." + this.name(); } - public boolean isVerifications() { + boolean isVerifications() { String blockType = this.name(); return blockType.equals(Verifications.name()) || blockType.equals(FullVerifications.name()); } - public static String getSupportedTypesStr() { + static String getSupportedTypesStr() { StringBuilder sb = new StringBuilder(); Arrays.stream(values()).forEach(value -> sb.append(value).append(", ")); return sb.substring(0, sb.length() - 2); diff --git a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitFullVerificationsToMockitoTest.java b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitFullVerificationsToMockitoTest.java index dfdc0303e..20568995a 100644 --- a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitFullVerificationsToMockitoTest.java +++ b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitFullVerificationsToMockitoTest.java @@ -34,7 +34,7 @@ public void defaults(RecipeSpec spec) { @DocumentExample @Test - void whenTimes() { + void whenMultipleMocks() { //language=java rewriteRun( java( @@ -48,13 +48,18 @@ void whenTimes() { class MyTest { @Mocked Object myObject; + + @Mocked + String str; void test() { myObject.wait(10L, 10); myObject.wait(10L, 10); + str.notify(); new FullVerifications() {{ myObject.wait(anyLong, anyInt); times = 2; + str.notify(); }}; } } @@ -63,19 +68,24 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class MyTest { @Mock Object myObject; + + @Mock + String str; void test() { myObject.wait(10L, 10); myObject.wait(10L, 10); + str.notify(); verify(myObject, times(2)).wait(anyLong(), anyInt()); - verifyNoMoreInteractions(myObject); + verify(str).notify(); + verifyNoMoreInteractions(myObject, str); } } """ @@ -83,9 +93,8 @@ void test() { ); } - @DocumentExample @Test - void whenOtherStatements() { + void whenTimes() { //language=java rewriteRun( java( @@ -101,11 +110,12 @@ class MyTest { Object myObject; void test() { + myObject.wait(10L, 10); myObject.wait(10L, 10); new FullVerifications() {{ myObject.wait(anyLong, anyInt); + times = 2; }}; - System.out.println("bla"); } } """, @@ -123,9 +133,9 @@ class MyTest { void test() { myObject.wait(10L, 10); - verify(myObject).wait(anyLong(), anyInt()); + myObject.wait(10L, 10); + verify(myObject, times(2)).wait(anyLong(), anyInt()); verifyNoMoreInteractions(myObject); - System.out.println("bla"); } } """ @@ -133,8 +143,9 @@ void test() { ); } + @DocumentExample @Test - void whenMultipleMocks() { + void whenOtherStatements() { //language=java rewriteRun( java( @@ -148,19 +159,13 @@ void whenMultipleMocks() { class MyTest { @Mocked Object myObject; - - @Mocked - String str; void test() { myObject.wait(10L, 10); - myObject.wait(10L, 10); - str.notify(); new FullVerifications() {{ myObject.wait(anyLong, anyInt); - times = 2; - str.notify(); }}; + System.out.println("bla"); } } """, @@ -175,17 +180,12 @@ void test() { class MyTest { @Mock Object myObject; - - @Mock - String str; void test() { myObject.wait(10L, 10); - myObject.wait(10L, 10); - str.notify(); - verify(myObject, times(2)).wait(anyLong(), anyInt()); - verify(str).notify(); - verifyNoMoreInteractions(myObject, str); + verify(myObject).wait(anyLong(), anyInt()); + verifyNoMoreInteractions(myObject); + System.out.println("bla"); } } """ From ce50b6b7125d7f54053676e9aa3aba1a3268707e Mon Sep 17 00:00:00 2001 From: Shivani Sharma Date: Mon, 14 Oct 2024 02:11:33 +1100 Subject: [PATCH 3/9] Cleanup up jmockit to mockito migration further --- .../org/openrewrite/java/testing/jmockit/JMockitBlockType.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java index 19e2fa4f9..28cdbcc3f 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java @@ -34,8 +34,7 @@ enum JMockitBlockType { } boolean isVerifications() { - String blockType = this.name(); - return blockType.equals(Verifications.name()) || blockType.equals(FullVerifications.name()); + return this == Verifications || this == FullVerifications; } static String getSupportedTypesStr() { From 0a874ea71fe97e36a6d1dfc94bd6ceacc779e902 Mon Sep 17 00:00:00 2001 From: Shivani Sharma Date: Mon, 14 Oct 2024 02:24:38 +1100 Subject: [PATCH 4/9] Refactor jmockit to mockito migration --- .../java/testing/jmockit/JMockitBlockRewriter.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java index e6a023e0e..387a40c69 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java @@ -237,9 +237,7 @@ private void rewriteVerify(J.MethodInvocation invocation, @Nullable Expression t private void rewriteFullVerifications(List mocks) { StringBuilder sb = new StringBuilder(VERIFY_NO_INTERACTIONS_TEMPLATE_PREFIX); - for (int i = 0; i < mocks.size(); i++) { - sb.append(ANY_TEMPLATE_FIELD).append(","); // verifyNoMoreInteractions(mock1, mock2 ... - } + mocks.forEach(mock -> sb.append(ANY_TEMPLATE_FIELD).append(",")); // verifyNoMoreInteractions(mock1, mock2 ... sb.deleteCharAt(sb.length() - 1); sb.append(")"); rewriteTemplate(sb.toString(), mocks, nextStatementCoordinates); From f3329076312078b11808e234c1d0290d43b15f56 Mon Sep 17 00:00:00 2001 From: Shivani Sharma Date: Mon, 14 Oct 2024 02:40:50 +1100 Subject: [PATCH 5/9] Refactor jmockit to mockito migration for code reuse --- ...JMockitAnnotatedArgumentToMockitoTest.java | 20 +------------------ .../jmockit/JMockitDelegateToMockitoTest.java | 10 +--------- .../JMockitExpectationsToMockitoTest.java | 10 +--------- ...JMockitFullVerificationsToMockitoTest.java | 11 ++-------- .../java/testing/jmockit/JMockitTestBase.java | 14 +++++++++++++ .../JMockitVerificationsToMockitoTest.java | 11 ++-------- 6 files changed, 21 insertions(+), 55 deletions(-) create mode 100644 src/test/java/org/openrewrite/java/testing/jmockit/JMockitTestBase.java diff --git a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitAnnotatedArgumentToMockitoTest.java b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitAnnotatedArgumentToMockitoTest.java index aba68599f..c207bf351 100644 --- a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitAnnotatedArgumentToMockitoTest.java +++ b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitAnnotatedArgumentToMockitoTest.java @@ -17,28 +17,10 @@ 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; -class JMockitAnnotatedArgumentToMockitoTest implements RewriteTest { - @Override - public void defaults(RecipeSpec spec) { - spec - .parser(JavaParser.fromJavaVersion() - .logCompilationWarningsAndErrors(true) - .classpathFromResources(new InMemoryExecutionContext(), - "junit-jupiter-api-5.9", - "jmockit-1.49" - )) - .recipeFromResource( - "/META-INF/rewrite/jmockit.yml", - "org.openrewrite.java.testing.jmockit.JMockitToMockito" - ); - } +class JMockitAnnotatedArgumentToMockitoTest extends JMockitTestBase { @DocumentExample @Test diff --git a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitDelegateToMockitoTest.java b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitDelegateToMockitoTest.java index e4ad77bbd..b1282793d 100644 --- a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitDelegateToMockitoTest.java +++ b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitDelegateToMockitoTest.java @@ -19,11 +19,8 @@ import org.junit.jupiter.api.Test; import org.openrewrite.DocumentExample; import org.openrewrite.Issue; -import org.openrewrite.test.RecipeSpec; -import org.openrewrite.test.RewriteTest; import static org.openrewrite.java.Assertions.java; -import static org.openrewrite.java.testing.jmockit.JMockitTestUtils.setDefaultParserSettings; /** * At the moment, JMockit Delegates are not migrated to mockito. What I'm seeing is that they are being trashed @@ -32,12 +29,7 @@ */ @Disabled @Issue("https://github.com/openrewrite/rewrite-testing-frameworks/issues/522") -class JMockitDelegateToMockitoTest implements RewriteTest { - - @Override - public void defaults(RecipeSpec spec) { - setDefaultParserSettings(spec); - } +class JMockitDelegateToMockitoTest extends JMockitTestBase { @DocumentExample @Test diff --git a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitExpectationsToMockitoTest.java b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitExpectationsToMockitoTest.java index 27c27c838..1a98f6635 100644 --- a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitExpectationsToMockitoTest.java +++ b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitExpectationsToMockitoTest.java @@ -18,18 +18,10 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openrewrite.DocumentExample; -import org.openrewrite.test.RecipeSpec; -import org.openrewrite.test.RewriteTest; import static org.openrewrite.java.Assertions.java; -import static org.openrewrite.java.testing.jmockit.JMockitTestUtils.setDefaultParserSettings; -class JMockitExpectationsToMockitoTest implements RewriteTest { - - @Override - public void defaults(RecipeSpec spec) { - setDefaultParserSettings(spec); - } +class JMockitExpectationsToMockitoTest extends JMockitTestBase { @DocumentExample @Test diff --git a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitFullVerificationsToMockitoTest.java b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitFullVerificationsToMockitoTest.java index 20568995a..fd3ab16a1 100644 --- a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitFullVerificationsToMockitoTest.java +++ b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitFullVerificationsToMockitoTest.java @@ -17,20 +17,13 @@ import org.junit.jupiter.api.Test; import org.openrewrite.DocumentExample; -import org.openrewrite.test.RecipeSpec; -import org.openrewrite.test.RewriteTest; import static org.openrewrite.java.Assertions.java; -import static org.openrewrite.java.testing.jmockit.JMockitTestUtils.setDefaultParserSettings; /** * Not doing comprehensive testing as it is covered in JMockitVerificationsToMockitoTest and shares same code path */ -class JMockitFullVerificationsToMockitoTest implements RewriteTest { - @Override - public void defaults(RecipeSpec spec) { - setDefaultParserSettings(spec); - } +class JMockitFullVerificationsToMockitoTest extends JMockitTestBase { @DocumentExample @Test @@ -68,7 +61,7 @@ void test() { import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; - + import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) diff --git a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitTestBase.java b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitTestBase.java new file mode 100644 index 000000000..b780651d0 --- /dev/null +++ b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitTestBase.java @@ -0,0 +1,14 @@ +package org.openrewrite.java.testing.jmockit; + +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.testing.jmockit.JMockitTestUtils.setDefaultParserSettings; + +public class JMockitTestBase implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + setDefaultParserSettings(spec); + } +} diff --git a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitVerificationsToMockitoTest.java b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitVerificationsToMockitoTest.java index 148d2a737..6264a9ada 100644 --- a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitVerificationsToMockitoTest.java +++ b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitVerificationsToMockitoTest.java @@ -17,18 +17,11 @@ import org.junit.jupiter.api.Test; import org.openrewrite.DocumentExample; -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.java.testing.jmockit.JMockitTestUtils.setDefaultParserSettings; -class JMockitVerificationsToMockitoTest implements RewriteTest { - @Override - public void defaults(RecipeSpec spec) { - setDefaultParserSettings(spec); - } +class JMockitVerificationsToMockitoTest extends JMockitTestBase { @DocumentExample @Test @@ -684,7 +677,7 @@ class MyTest { void test() { myObject.wait(); - new Verifications() {{ + new Verifications() {{ myObject.wait(); myObject.wait(anyLong, anyInt); }}; From 5156f2efe4361ef4e448ad396374d486cd45e4fc Mon Sep 17 00:00:00 2001 From: Shivani Sharma Date: Mon, 14 Oct 2024 02:42:27 +1100 Subject: [PATCH 6/9] Cleanup jmockit to mockito base test class --- .../org/openrewrite/java/testing/jmockit/JMockitTestBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitTestBase.java b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitTestBase.java index b780651d0..ed41e9263 100644 --- a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitTestBase.java +++ b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitTestBase.java @@ -5,7 +5,7 @@ import static org.openrewrite.java.testing.jmockit.JMockitTestUtils.setDefaultParserSettings; -public class JMockitTestBase implements RewriteTest { +class JMockitTestBase implements RewriteTest { @Override public void defaults(RecipeSpec spec) { From 717c54620fadfa3048a2dd3a02131b2502d37da4 Mon Sep 17 00:00:00 2001 From: Shivani Sharma Date: Mon, 14 Oct 2024 02:48:21 +1100 Subject: [PATCH 7/9] Refactor jmockit to mockito --- .../openrewrite/java/testing/jmockit/JMockitBlockType.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java index 28cdbcc3f..c691d97b6 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockType.java @@ -27,11 +27,7 @@ enum JMockitBlockType { Verifications, FullVerifications; - private final String fqn; - - JMockitBlockType() { - this.fqn = "mockit." + this.name(); - } + private final String fqn = "mockit." + this.name(); boolean isVerifications() { return this == Verifications || this == FullVerifications; From a4b96fc581255e5cbd382fcb216974838d3f60d1 Mon Sep 17 00:00:00 2001 From: Shivani Sharma Date: Mon, 14 Oct 2024 03:13:47 +1100 Subject: [PATCH 8/9] Refactor jmockit to mockito full verifications --- .../testing/jmockit/JMockitBlockRewriter.java | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java index 387a40c69..db8b9631f 100644 --- a/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java +++ b/src/main/java/org/openrewrite/java/testing/jmockit/JMockitBlockRewriter.java @@ -101,19 +101,22 @@ J.Block rewriteMethodBody() { for (Statement jmockitBlockStatement : jmockitBlock.getStatements()) { if (jmockitBlockStatement instanceof J.MethodInvocation) { J.MethodInvocation invocation = (J.MethodInvocation) jmockitBlockStatement; - J.Identifier object = (J.Identifier) invocation.getSelect(); - if (object != null) { + Expression select = invocation.getSelect(); + if (select instanceof J.Identifier) { + J.Identifier mockObj = (J.Identifier) select; // ensure it's not a returns statement, we add that later to related statements if (!invocation.getName().getSimpleName().equals("returns")) { methodInvocationIdx++; methodInvocationsToRewrite.add(new ArrayList<>()); } - if (uniqueMocks.stream().noneMatch(mock -> mock.getType().equals(object.getType()) && mock.getSimpleName().equals(object.getSimpleName()))) { - uniqueMocks.add(object); + if (isFullVerifications() && uniqueMocks.stream().noneMatch(mock -> mock.getType().equals(mockObj.getType()) + && mock.getSimpleName().equals(mockObj.getSimpleName()))) { + uniqueMocks.add(mockObj); } } } + // add the statements corresponding to the method invocation if (methodInvocationIdx != -1) { methodInvocationsToRewrite.get(methodInvocationIdx).add(jmockitBlockStatement); } @@ -127,12 +130,16 @@ J.Block rewriteMethodBody() { // now rewrite methodInvocationsToRewrite.forEach(this::rewriteMethodInvocation); - if (blockType == FullVerifications) { - rewriteFullVerifications(new ArrayList<>(uniqueMocks)); + if (isFullVerifications()) { + rewriteFullVerify(new ArrayList<>(uniqueMocks)); } return methodBody; } + private boolean isFullVerifications() { + return this.blockType == FullVerifications; + } + private void rewriteMethodInvocation(List statementsToRewrite) { final MockInvocationResults mockInvocationResults = buildMockInvocationResults(statementsToRewrite); if (mockInvocationResults == null) { @@ -235,15 +242,17 @@ private void rewriteVerify(J.MethodInvocation invocation, @Nullable Expression t } } - private void rewriteFullVerifications(List mocks) { - StringBuilder sb = new StringBuilder(VERIFY_NO_INTERACTIONS_TEMPLATE_PREFIX); - mocks.forEach(mock -> sb.append(ANY_TEMPLATE_FIELD).append(",")); // verifyNoMoreInteractions(mock1, mock2 ... - sb.deleteCharAt(sb.length() - 1); - sb.append(")"); - rewriteTemplate(sb.toString(), mocks, nextStatementCoordinates); - if (!this.rewriteFailed) { - setNextStatementCoordinates(++numStatementsAdded); - visitor.maybeAddImport(MOCKITO_IMPORT_FQN_PREFX, "verifyNoMoreInteractions", false); + private void rewriteFullVerify(List mocks) { + if (!mocks.isEmpty()) { + StringBuilder sb = new StringBuilder(VERIFY_NO_INTERACTIONS_TEMPLATE_PREFIX); + mocks.forEach(mock -> sb.append(ANY_TEMPLATE_FIELD).append(",")); // verifyNoMoreInteractions(mock1, mock2 ... + sb.deleteCharAt(sb.length() - 1); + sb.append(")"); + rewriteTemplate(sb.toString(), mocks, nextStatementCoordinates); + if (!this.rewriteFailed) { + setNextStatementCoordinates(++numStatementsAdded); + visitor.maybeAddImport(MOCKITO_IMPORT_FQN_PREFX, "verifyNoMoreInteractions", false); + } } } From 8b123fd5cd87519a6909780c0acd88cc9ddb9b5f Mon Sep 17 00:00:00 2001 From: Shivani Sharma Date: Mon, 14 Oct 2024 12:25:20 +1100 Subject: [PATCH 9/9] Add license to test base class --- .../java/testing/jmockit/JMockitTestBase.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitTestBase.java b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitTestBase.java index ed41e9263..bc7b59deb 100644 --- a/src/test/java/org/openrewrite/java/testing/jmockit/JMockitTestBase.java +++ b/src/test/java/org/openrewrite/java/testing/jmockit/JMockitTestBase.java @@ -1,3 +1,18 @@ +/* + * Copyright 2023 the original author or authors. + *

+ * 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 + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.jmockit; import org.openrewrite.test.RecipeSpec;