Skip to content

mockStatic error in JmockitToMockito #776

@wuxudong

Description

@wuxudong

What version of OpenRewrite are you using?

I am using

  • Maven/Gradle plugin 6.15.0
  • rewrite-test-framework 3.14.1

How are you running OpenRewrite?

I am using the Maven plugin, and my project is a single module project.

            <plugin>
                <groupId>org.openrewrite.maven</groupId>
                <artifactId>rewrite-maven-plugin</artifactId>
                <version>6.15.0</version>
                <configuration>
                    <exportDatatables>true</exportDatatables>
                    <activeRecipes>
                        <recipe>org.openrewrite.java.testing.jmockit.JMockitToMockito</recipe>
                    </activeRecipes>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.openrewrite.recipe</groupId>
                        <artifactId>rewrite-testing-frameworks</artifactId>
                        <version>3.14.1</version>
                    </dependency>
                </dependencies>
            </plugin>

What is the smallest, simplest way to reproduce the problem?

import package1.Param;
import mockit.Mock;
import mockit.MockUp;
import org.junit.Assert;
import org.junit.Test;

public class Utils {
    public static void check(package1.Param param) {
    }

    public static void check(package2.Param param) {
    }
}

public class MockupTest {
    @Test
    public void testFoo() {
        new MockUp<Utils>() {
            @Mock
            public void check(package1.Param param) {
                Assert.assertEquals("sub1", param.getName());
            }

            @Mock
            public void check(package2.Param param) {
                Assert.assertEquals("sub2", param.getName());
            }
        };

        Utils.check(new Param("sub1"));
    }
}

What did you expect to see?

import package1.Param;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.MockedStatic;

import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.mockStatic;

public class MockupTest {
    @Test
    public void testFoo() {
        try (MockedStatic mockStaticUtils = mockStatic(Utils.class)) {
            mockStaticUtils.when(() -> Utils.check(nullable(package1.Param.class))).thenAnswer(invocation -> {
                Param param = invocation.getArgument(0);
                Assert.assertEquals("sub2", param.getName());
                return null;
            });
            mockStaticUtils.when(() -> Utils.check(nullable(package1.Param.class))).thenAnswer(invocation -> {
                Param param = invocation.getArgument(0);
                Assert.assertEquals("sub1", param.getName());
                return null;
            });
            mockStaticUtils.when(() -> Utils.failedCheck()).thenCallRealMethod();
            mockStaticUtils.when(() -> Utils.bar()).thenCallRealMethod();
            mockStaticUtils.when(() -> Utils.foo()).thenCallRealMethod();

            Utils.check(new Param("sub1"));
        }
    }
}

What did you see instead?

import package1.Param;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.MockedStatic;

import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.mockStatic;

public class MockupTest {
    @Test
    public void testFoo() {
        try (MockedStatic mockStaticUtils = mockStatic(Utils.class)) {
            mockStaticUtils.when(() -> Utils.check(nullable(Param.class))).thenAnswer(invocation -> {
                Param param = invocation.getArgument(0);
                Assert.assertEquals("sub2", param.getName());
                return null;
            });
            mockStaticUtils.when(() -> Utils.check(nullable(Param.class))).thenAnswer(invocation -> {
                Param param = invocation.getArgument(0);
                Assert.assertEquals("sub1", param.getName());
                return null;
            });
            mockStaticUtils.when(() -> Utils.failedCheck()).thenCallRealMethod();
            mockStaticUtilsls.when(() -> Utils.bar()).thenCallRealMethod();
            mockStaticUtilsls.when(() -> Utils.foo()).thenCallRealMethod();

            Utils.check(new Param("sub1"));
);      }
    }
}

What is the full stack trace of any errors you encountered?

Are you interested in contributing a fix to OpenRewrite?

There are two problems in the converted code:

  1. FullQualifiedName is necessary when two class have same simple name. eg package1.Param and package2.Param
  2. CallRealMethod introduces syntax error.

After digging the code, I found the two problem can be fixed by

Image
  1. use
return "nullable(" + TypeUtils.asFullyQualified(s).getFullyQualifiedName() + ".class)";

instead of

return "nullable(" + TypeUtils.asFullyQualified(s).getClassName() + ".class)";
  1. remove redundant ");" in mockStatic. and BTW, use "mockStatic(Utils.class, Mockito.CALLS_REAL_METHODS)" can be more compact than a lot of "mockStaticUtils.when(() -> Utils.failedCheck()).thenCallRealMethod();". It will be hard to maintain if the Utils have hundreds of static methods and only mock serval methods.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions