Skip to content

Commit ccae913

Browse files
zenghu1chentimtebeekgithub-actions[bot]
authored
JMockit to Mockito Recipe - Rewrite JMockit Mocked Variable to Mockito statements (#481)
* JMockit to Mockito Recipe - Rewrite JMockit Mocked Variable to Mockito statements * remove debug code * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Remove unused imports and add missing test annotation * Use ListUtils.map and FindAnnotations.find --------- Co-authored-by: Tim te Beek <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Tim te Beek <[email protected]>
1 parent 95ea111 commit ccae913

File tree

3 files changed

+231
-0
lines changed

3 files changed

+231
-0
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.openrewrite.java.testing.jmockit;
17+
18+
import lombok.EqualsAndHashCode;
19+
import lombok.Value;
20+
import org.openrewrite.ExecutionContext;
21+
import org.openrewrite.Preconditions;
22+
import org.openrewrite.Recipe;
23+
import org.openrewrite.TreeVisitor;
24+
import org.openrewrite.internal.ListUtils;
25+
import org.openrewrite.internal.lang.NonNullApi;
26+
import org.openrewrite.java.JavaIsoVisitor;
27+
import org.openrewrite.java.JavaParser;
28+
import org.openrewrite.java.JavaTemplate;
29+
import org.openrewrite.java.search.FindAnnotations;
30+
import org.openrewrite.java.search.UsesType;
31+
import org.openrewrite.java.tree.J;
32+
import org.openrewrite.java.tree.Statement;
33+
34+
import java.util.ArrayList;
35+
import java.util.List;
36+
37+
@Value
38+
@EqualsAndHashCode(callSuper = false)
39+
@NonNullApi
40+
public class JMockitMockedVariableToMockito extends Recipe {
41+
@Override
42+
public String getDisplayName() {
43+
return "Rewrite JMockit Mocked Variable";
44+
}
45+
46+
@Override
47+
public String getDescription() {
48+
return "Rewrites JMockit `Mocked Variable` to Mockito statements.";
49+
}
50+
51+
@Override
52+
public TreeVisitor<?, ExecutionContext> getVisitor() {
53+
return Preconditions.check(new UsesType<>("mockit.Mocked", false),
54+
new RewriteMockedVariableVisitor());
55+
}
56+
57+
private static class RewriteMockedVariableVisitor extends JavaIsoVisitor<ExecutionContext> {
58+
@Override
59+
public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration methodDeclaration, ExecutionContext ctx) {
60+
J.MethodDeclaration md = super.visitMethodDeclaration(methodDeclaration, ctx);
61+
62+
List<Statement> parameters = md.getParameters();
63+
if (!parameters.isEmpty() && !(parameters.get(0) instanceof J.Empty)) {
64+
maybeRemoveImport("mockit.Mocked");
65+
maybeAddImport("org.mockito.Mockito");
66+
67+
// Create lists to store the mocked parameters and the new type parameters
68+
List<J.VariableDeclarations> mockedParameter = new ArrayList<>();
69+
70+
// Remove any mocked parameters from the method declaration
71+
md = md.withParameters(ListUtils.map(parameters, parameter -> {
72+
if (parameter instanceof J.VariableDeclarations) {
73+
J.VariableDeclarations variableDeclarations = (J.VariableDeclarations) parameter;
74+
// Check if the parameter has the annotation "mockit.Mocked"
75+
if (!FindAnnotations.find(variableDeclarations, "mockit.Mocked").isEmpty()) {
76+
mockedParameter.add(variableDeclarations);
77+
return null;
78+
}
79+
}
80+
return parameter;
81+
}));
82+
83+
// Add mocked parameters as statements to the method declaration
84+
if (!mockedParameter.isEmpty()) {
85+
JavaTemplate addStatementsTemplate = JavaTemplate.builder("#{} #{} = Mockito.mock(#{}.class);\n")
86+
.javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "mockito-core-3.12"))
87+
.imports("org.mockito.Mockito")
88+
.contextSensitive()
89+
.build();
90+
// Retain argument order by iterating in reverse
91+
for (int i = mockedParameter.size() - 1; i >= 0; i--) {
92+
J.VariableDeclarations variableDeclarations = mockedParameter.get(i);
93+
// Apply the template and update the method declaration
94+
md = addStatementsTemplate.apply(updateCursor(md),
95+
md.getBody().getCoordinates().firstStatement(),
96+
variableDeclarations.getTypeExpression().toString(),
97+
variableDeclarations.getVariables().get(0).getSimpleName(),
98+
variableDeclarations.getTypeExpression().toString());
99+
}
100+
}
101+
}
102+
103+
return md;
104+
}
105+
}
106+
}

src/main/resources/META-INF/rewrite/jmockit.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ tags:
2323
- jmockit
2424
recipeList:
2525
- org.openrewrite.java.testing.jmockit.JMockitExpectationsToMockito
26+
- org.openrewrite.java.testing.jmockit.JMockitMockedVariableToMockito
2627
- org.openrewrite.java.ChangeType:
2728
oldFullyQualifiedTypeName: mockit.Mocked
2829
newFullyQualifiedTypeName: org.mockito.Mock
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.openrewrite.java.testing.jmockit;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.openrewrite.DocumentExample;
20+
import org.openrewrite.InMemoryExecutionContext;
21+
import org.openrewrite.java.JavaParser;
22+
import org.openrewrite.test.RecipeSpec;
23+
import org.openrewrite.test.RewriteTest;
24+
25+
import static org.openrewrite.java.Assertions.java;
26+
27+
class JMockitMockedVariableToMockitoTest implements RewriteTest {
28+
@Override
29+
public void defaults(RecipeSpec spec) {
30+
spec
31+
.parser(JavaParser.fromJavaVersion()
32+
.logCompilationWarningsAndErrors(true)
33+
.classpathFromResources(new InMemoryExecutionContext(),
34+
"junit-jupiter-api-5.9",
35+
"jmockit-1.49",
36+
"mockito-core-3.12",
37+
"mockito-junit-jupiter-3.12"
38+
))
39+
.recipeFromResource(
40+
"/META-INF/rewrite/jmockit.yml",
41+
"org.openrewrite.java.testing.jmockit.JMockitToMockito"
42+
);
43+
}
44+
45+
@DocumentExample
46+
@Test
47+
void mockedVariableTest() {
48+
//language=java
49+
rewriteRun(
50+
java(
51+
"""
52+
import mockit.Mocked;
53+
54+
import static org.junit.jupiter.api.Assertions.assertNotNull;
55+
56+
class A {
57+
@Mocked
58+
Object mockedObject;
59+
60+
void test(@Mocked Object o, @Mocked Object o2) {
61+
assertNotNull(o);
62+
assertNotNull(o2);
63+
}
64+
}
65+
""",
66+
"""
67+
import org.mockito.Mock;
68+
import org.mockito.Mockito;
69+
70+
import static org.junit.jupiter.api.Assertions.assertNotNull;
71+
72+
class A {
73+
@Mock
74+
Object mockedObject;
75+
76+
void test() {
77+
Object o = Mockito.mock(Object.class);
78+
Object o2 = Mockito.mock(Object.class);
79+
assertNotNull(o);
80+
assertNotNull(o2);
81+
}
82+
}
83+
"""
84+
)
85+
);
86+
}
87+
88+
@Test
89+
void noVariableTest() {
90+
rewriteRun(
91+
//language=java
92+
java(
93+
"""
94+
import mockit.Mocked;
95+
96+
import static org.junit.jupiter.api.Assertions.assertNotNull;
97+
98+
class A {
99+
@Mocked
100+
Object mockedObject;
101+
102+
void test() {
103+
assertNotNull(mockedObject);
104+
}
105+
}
106+
""",
107+
"""
108+
import org.mockito.Mock;
109+
110+
import static org.junit.jupiter.api.Assertions.assertNotNull;
111+
112+
class A {
113+
@Mock
114+
Object mockedObject;
115+
116+
void test() {
117+
assertNotNull(mockedObject);
118+
}
119+
}
120+
"""
121+
)
122+
);
123+
}
124+
}

0 commit comments

Comments
 (0)