EclEmma,powermock和Java 7问题

时间:2017-03-03 05:57:35

标签: unit-testing mockito powermock javassist eclemma

我正在使用Powermock但是当我运行Eclemma覆盖时,由于EclEmma的已知问题,Powermock测试用例不会被考虑在最终得分中。

我搜索的这个以及stackoverflow上的其他答案建议:

@Rule
public PowerMockRule rule = new PowerMockRule();

static {
 PowerMockAgent.initializeIfNeeded();
}

然后添加像powermock-module-javaagent,powermock-module-junit4-rule-agent这样的jar。

执行此操作后,当我运行我的代码然后找到错误:

java.lang.VerifyError: Expecting a stackmap frame at branch target 7

对于这个答案,建议使用各种版本的javassit。但是我无法完成这项工作并得到同样的错误。

我的pom.xml看起来像:

<dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito</artifactId>
        <version>1.6.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4</artifactId>
        <version>1.6.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-javaagent</artifactId>
        <version>1.6.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.powermock</groupId>
      <artifactId>powermock-module-junit4-rule-agent</artifactId>
      <version>1.6.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.javassist</groupId>
      <artifactId>javassist</artifactId>
      <version>3.21.0-GA</version>
      <scope>test</scope>
    </dependency>

如何让PowerMock测试用例包含在最终的Eclemma评分中?

2 个答案:

答案 0 :(得分:2)

我最喜欢的不回答:不要浪费你的时间。

相反,请将此作为另一个提示,不应使用PowerMock;并利用您的时间和精力学习如何编写更好的生产代码,无需PowerMock即可对其进行测试。

例如,开始研究那些videos;要理解避免调用静态(以不可测试的方式)方式的代码通常是错误的代码;并且改进此代码不仅可以帮助您摆脱PowerMock,还可以改善您的所有产品。

万一你发现要离开PowerMock很难;我的建议:然后把你的测试放到两个桶中(一个用于那些真正使用PowerMock的东西,只有PowerMock可以做的东西;一个用于所有其他的);并且只测量后一个的覆盖范围。这也将打开一条前进的道路&#34;:简单地避免将PowerMock用于任何新事物。相反,你可以转向mockito,这在过去的几年里有所改善;甚至允许你(实验上)像重写最终方法。

答案 1 :(得分:0)

我找到了一种方法,可能不干净,但我认为它有效。
所以问题陈述是如何让Powermock被包含在EclEmma中?
方法的第一个变化是转向Eclemma的maven方法,即 jacoco
在转到答案之前,请随时通过以下链接:

Power mock with jacoco
Basic of Java Instrumentation

简而言之,jacoco通过在加载时使用锁定/更新字节码/检测类来识别代码覆盖率。
并且其工作的powermock也锁定/更新字节码/检测它的功能但它是从磁盘而不是记忆
因此,当jacoco提供覆盖时,powermock类不会被覆盖,因为powermock从磁盘文件运行测试用例,jacoco不知道powermock在做什么。
因此,围绕它将jacoco检测的类存储在磁盘上,然后使用powermock运行测试通过这些类,然后让jacoco知道测试正在运行并将它们包含在代码覆盖中。 [PLS FEEL可以自由地纠正我对此的理解]
所以最终的代码更改是:

    <dependency>
        <groupId>org.jacoco</groupId>
        <artifactId>org.jacoco.agent</artifactId>
        <version>0.7.7.201606060606</version>
        <classifier>runtime</classifier>
    </dependency>
    <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
        <version>3.6.1</version>
        <scope>test</scope>
    </dependency>

<build>
    <plugins>
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <configuration>
                <excludes>
                 // files you want to exclude
                </excludes>
            </configuration>
            <executions>
                <execution>
                    <id>default-instrument</id>
                    <goals>
                        <goal>instrument</goal>
                    </goals>
                </execution>
                <execution>
                    <id>default-restore-instrumented-classes</id>
                    <goals>
                        <goal>restore-instrumented-classes</goal>
                    </goals>
                </execution>
                <execution>
                    <id>report</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>report</goal>
                    </goals>
                    <configuration>
                        <dataFile>${project.build.directory}/coverage.exec</dataFile>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <systemPropertyVariables>
                    <jacoco-agent.destfile>${project.build.directory}/coverage.exec</jacoco-agent.destfile>
                </systemPropertyVariables>
            </configuration>
        </plugin>
    </plugins>
</build>

这次运行后-PcodeCoverage为我解决了。