PowerMock + Mockito嘲笑构造函数不起作用

时间:2018-02-14 18:52:18

标签: constructor mockito powermock powermockito maven-surefire-plugin

我在运行一个简单的测试时遇到了麻烦,相应地,在互联网上找到的所有示例都应该没有任何问题。

我有一个带有以下pom.xml的Java 8 Maven项目:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>testingPowerMock</groupId>
    <artifactId>constructorMocking</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>TestingPowerMock</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.19.1</version>
                    <dependencies>
                        <dependency>
                            <groupId>org.junit.platform</groupId>
                            <artifactId>junit-platform-surefire-provider</artifactId>
                            <version>1.0.3</version>
                        </dependency>
                        <dependency>
                            <groupId>org.junit.jupiter</groupId>
                            <artifactId>junit-jupiter-engine</artifactId>
                            <version>5.1.0-M1</version>
                        </dependency>
                    </dependencies>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.1.0-RC1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.1.0-RC1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>1.6.6</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito2</artifactId>
            <version>1.6.6</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

当我使用JUnit5时,我只能使用SureFire插件从命令行运行测试,命令为:mvn clean test

我创建了这两个非常简单的类:

public class Created {

    private String message;

    public Created(String message) {

        this.message = message;

    }

    public String getMessage() {

        return this.message;

    }

}

public class Creator {

    public Created create() {

        return new Created("Another message");

    }

}

当我运行以下测试时,它会失败。

@RunWith(PowerMockRunner.class)
@PrepareForTest(Creator.class)
public class RunnerTest {

    @Test
    public void test() throws Exception {

        Creator creator = new Creator();
        Created created = mock(Created.class);

        when(created.getMessage()).thenReturn("The expected message");

        whenNew(Created.class).withAnyArguments().thenReturn(created);

        Created aNewlyCreatedObject = creator.create();

        assertEquals("The expected message", aNewlyCreatedObject.getMessage());


    }

}

看起来构造函数调用没有被截获,因为Mockito没有代理它。我尝试了不同版本的依赖项,但没有运气。我还尝试使用以下方法更改代码:

    whenNew(Created.class).withArguments("Another message").thenReturn(created);

    whenNew(Created.class).withArguments(anyString()).thenReturn(created);

但这些方法都没有改变测试的结果。

有人可以帮我解决这个问题吗?

谢谢

2 个答案:

答案 0 :(得分:2)

事实证明,降级到JUnit4解决了这个问题。

在最终的pom.xml下面,用于成功运行测试。改变PowerMock版本似乎没有任何影响,因为我尝试使用1.6.6,1.7.1和2.0.0-beta.5。我将向Powermock团队发布一个错误。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>testingPowerMock</groupId>
    <artifactId>constructorMocking</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>TestingPowerMock</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.20.1</version>
                    <dependencies>
                        <dependency>
                            <groupId>org.apache.maven.surefire</groupId>
                            <artifactId>surefire-junit47</artifactId>
                            <version>2.20.1</version>
                        </dependency>
                    </dependencies>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>1.7.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito2</artifactId>
            <version>1.7.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

答案 1 :(得分:0)

Apparently PowerMock does not support jUnit5 (yet?). Here is the epic for adding jUnit5 support. https://github.com/powermock/powermock/issues/830. It is too bad they don't have the resources to fix PowerMock because it is really a very powerful framework to make unit tests for legacy applications.

To my opinion when you need PowerMock to make a unit test, the class you try to test isn't written correctly and should be refactored to be testable. Only for legacy code this is sometimes too much to ask and therefor PowerMock gives you the ability to test an otherwise untestable class.