【问题标题】:PowerMock + Emma - code coverage showing 0% for private static methods and other methods too [duplicate]PowerMock + Emma - 私有静态方法和其他方法的代码覆盖率也显示为 0% [重复]
【发布时间】:2019-02-03 10:57:30
【问题描述】:

我从 Mock private method using PowerMockito 获取了 PowerMock 的参考,并在此处应用了相同的逻辑。另外,我在 eclipse/STS 中安装了 EMMA(开源工具),但是当我运行代码时,我看到代码覆盖率为零。为什么?

public class MyClient {

    public void publicApi() {
        System.out.println("In publicApi");
        int result = 0;
        try {
            result = privateApi("hello", 1);
        } catch (Exception e) {
            //Assert.fail();
        }
        System.out.println("result : "+result);
        if (result == 20) {
            throw new RuntimeException("boom");
        }
    }

    private static int privateApi(String whatever, int num) throws Exception {
        System.out.println("In privateAPI");
        thirdPartyCall();
        int resp = 10;
        return resp;
    }

    private static void thirdPartyCall() throws Exception{
        System.out.println("In thirdPartyCall");
        //Actual WS call which may be down while running the test cases
    }
}

MyClientTest.java

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClient.class)
public class MyClientTest {

    @Test
    public void testPublicAPI() throws Exception {
        PowerMockito.mockStatic(MyClient.class);

        //PowerMockito.doReturn(10).when(MyClient.class, "privateApi", anyString(), anyInt());
        PowerMockito.when(MyClient.class,"privateApi", anyString(), anyInt()).thenReturn(anyInt());
    }
}

实际代码覆盖率:

pom.xml

<dependencies>
        <!-- Power Mock -->
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito</artifactId>
            <version>1.7.4</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>1.7.4</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4-rule-agent</artifactId>
            <version>1.7.4</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-core</artifactId>
            <version>1.7.4</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

【问题讨论】:

  • 您似乎准备了用于测试的静态方法(即通过PowerMockito.mockStatic(...)@PrepareForTest(...) 操作字节码),我可以看到您正在设置测试/模拟行为(使用PowerMockito 的@ 987654329@),但@user298396 是对的 - 您的测试中似乎没有任何东西实际上正在锻炼/调用您的测试类...?
  • PowerMock + ECLemma:覆盖数据损坏。习惯它。要么尝试 cobertura,要么(老实说,更好的方法):学习如何编写 易于测试 无需 PowerMock(ito) 字节码操作巫毒魔法即可测试的生产代码。

标签: java powermock powermockito


【解决方案1】:

如果您正在构建一个 Spy 或 Mock,那么您不会调用实际的测试代码。间谍的重点是能够verify() 他们,以便通过调用正确的回调或方法来检查您的代码行为是否正确。在 mock 的情况下,关键是引导代码沿着特定的控制流路径向下,并且还要引导到 verify() 与 mock 的预期交互。

由于您的测试用例调用了间谍的测试方法,因此您的代码覆盖率正好是 0% 也就不足为奇了。如果您要验证与模拟方法的交互,您可能会发现没有发生任何事情。

您想要做的是设置您的模拟,但以“正常方式”调用实际测试代码。这个想法是启动执行环境,然后“正常”调用测试的方法调用,最后观察实际发生的情况。最后一点包括对生成的输出的正常断言、预期交互的验证(这些都发生了,而且这些都涉及预期的参数/值)。

更改您的测试代码:

MyClient classUnderTest = PowerMockito.spy(new MyClient());

收件人:

MyClient classUnderTest = new MyClient();

并观察代码覆盖率。

【讨论】:

  • 看看你的测试代码。只要您的被测单元只是一个间谍,您就不会触及您的实际实现,而是模拟/间谍框架为您合成的任何代理。所以你得到 0% 的代码覆盖率。
  • 至于模拟的好处是:准备好你的执行环境,即模拟你的被测单元的依赖行为。您可以使用模拟来确保根据您的测试用例的需要采用或不采用特定的控制流分支。
  • 您应该调用实际的被测单元。基本上这条线是错误的:MyClient classUnderTest = PowerMockito.spy(new MyClient()); 因为这给了你一个间谍,而不是被测的实际单元。请记住:间谍不是您要测试的实际代码!
  • 只需像在其他非测试代码中一样正常构建您的测试单元。
  • 仍然没有帮助。您能否尝试在您最后运行此代码?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-31
  • 2020-05-26
相关资源
最近更新 更多