Skip to content

Commit

Permalink
Jmockit Expectations with no times or result should be transformed to…
Browse files Browse the repository at this point in the history
… Mockito verify statement (#530)

* Ensure Jmockit expectations with no times or result transform to a mockito verify

* Minor polish to text blocks

* Make times, minTimes, maxTimes more flexible as it was originally so even if someone mistakenly puts times and minTimes together, it still migrates without issue

---------

Co-authored-by: Tim te Beek <tim@moderne.io>
  • Loading branch information
shivanisky and timtebeek authored Jun 20, 2024
1 parent 6a58d6c commit 288c9ef
Show file tree
Hide file tree
Showing 2 changed files with 352 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import org.openrewrite.Cursor;
import org.openrewrite.ExecutionContext;
import org.openrewrite.internal.lang.Nullable;
import org.openrewrite.java.JavaParser;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.JavaVisitor;
Expand Down Expand Up @@ -118,22 +119,31 @@ private void rewriteMethodBody(List<Statement> expectationStatements) {
return;
}
J.MethodInvocation invocation = (J.MethodInvocation) expectationStatements.get(0);
if (!mockInvocationResults.getResults().isEmpty()) {
boolean hasExpectationsResults = !mockInvocationResults.getResults().isEmpty();
if (hasExpectationsResults) {
// rewrite the statement to mockito if there are results
rewriteExpectationResult(mockInvocationResults.getResults(), invocation);
} else if (nextStatementCoordinates.isReplacement()) {
// if there are no results and the Expectations block is not yet replaced, remove it
removeExpectationsStatement();
}

boolean hasTimes = false;
if (mockInvocationResults.getTimes() != null) {
hasTimes = true;
writeMethodVerification(invocation, mockInvocationResults.getTimes(), "times");
}
if (mockInvocationResults.getMinTimes() != null) {
hasTimes = true;
writeMethodVerification(invocation, mockInvocationResults.getMinTimes(), "atLeast");
}
if (mockInvocationResults.getMaxTimes() != null) {
hasTimes = true;
writeMethodVerification(invocation, mockInvocationResults.getMaxTimes(), "atMost");
}
if (!hasExpectationsResults && !hasTimes) {
writeMethodVerification(invocation, null, null);
}
}

private void rewriteExpectationResult(List<Expression> results, J.MethodInvocation invocation) {
Expand Down Expand Up @@ -182,18 +192,22 @@ private void removeExpectationsStatement() {
methodBody.getStatements().get(bodyStatementIndex + numStatementsAdded).getCoordinates().after();
}

private void writeMethodVerification(J.MethodInvocation invocation, Expression times, String verificationMode) {
private void writeMethodVerification(J.MethodInvocation invocation, @Nullable Expression times, @Nullable String verificationMode) {
String fqn = getInvocationSelectFullyQualifiedClassName(invocation);
if (fqn == null) {
// cannot write a verification statement for an invocation without a select field
return;
}
visitor.maybeAddImport("org.mockito.Mockito", "verify");
visitor.maybeAddImport("org.mockito.Mockito", verificationMode);
if (verificationMode != null) {
visitor.maybeAddImport("org.mockito.Mockito", verificationMode);
}

List<Object> templateParams = new ArrayList<>();
templateParams.add(invocation.getSelect());
templateParams.add(times);
if (times != null) {
templateParams.add(times);
}
templateParams.add(invocation.getName().getSimpleName());

String verifyTemplate = getVerifyTemplate(invocation.getArguments(), fqn, verificationMode, templateParams);
Expand Down Expand Up @@ -251,17 +265,20 @@ private static void appendToTemplate(StringBuilder templateBuilder, boolean buil
templateBuilder.append(templateField);
}

private static String getVerifyTemplate(List<Expression> arguments, String fqn, String verificationMode, List<Object> templateParams) {
private static String getVerifyTemplate(List<Expression> arguments, String fqn, @Nullable String verificationMode, List<Object> templateParams) {
StringBuilder templateBuilder = new StringBuilder("verify(#{any(" + fqn + ")}"); // verify(object
if (verificationMode != null) {
templateBuilder.append(", ").append(verificationMode).append("(#{any(int)})"); // verify(object, times(2)
}
templateBuilder.append(").#{}("); // verify(object, times(2)).method(

if (arguments.isEmpty()) {
return "verify(#{any(" + fqn + ")}, "
+ verificationMode
+ "(#{any(int)})).#{}();";
templateBuilder.append(");"); // verify(object, times(2)).method();
return templateBuilder.toString();
}
StringBuilder templateBuilder = new StringBuilder("verify(#{any(" + fqn + ")}, "
+ verificationMode
+ "(#{any(int)})).#{}(");

boolean hasArgument = false;
for (Expression argument : arguments) {
for (Expression argument : arguments) { // verify(object, times(2).method(anyLong(), any Int()
if (argument instanceof J.Empty) {
continue;
} else if (argument instanceof J.Literal) {
Expand All @@ -276,7 +293,7 @@ private static String getVerifyTemplate(List<Expression> arguments, String fqn,
if (hasArgument) {
templateBuilder.delete(templateBuilder.length() - 2, templateBuilder.length());
}
templateBuilder.append(");");
templateBuilder.append(");"); // verify(object, times(2).method(anyLong(), any Int());
return templateBuilder.toString();
}

Expand Down
Loading

0 comments on commit 288c9ef

Please sign in to comment.