【问题标题】:Offline Jacoco using MockStatic cause re-instrumentation exception离线 Jacoco 使用 MockStatic 导致重新检测异常
【发布时间】:2016-02-03 07:10:08
【问题描述】:

我正在运行 PowerMock 1.6.4 和所有最新版本(尽管是 JUnit 4.11)。

  • 我使用 Jacoco Ant 任务仅检测类,而不是测试类。我还使用 Jacoco ant 任务运行 Junit 测试,然后生成报告。

现在我遇到了一个我无法解决的问题......

  • 我有一个测试类,它测试 Foo 类的一个成员函数。
  • Foo 的成员之一是静态的,所以我将它包装在一个静态函数中,这样我就可以通过 mock 控制执行,但副作用是我现在需要 mockStatic。

我注意到的是 PowerMockito.mockStatic(Foo.class) ...所有测试都因仪器问题而失败。

我有另一个测试类来测试 Foo 的另一个成员函数。这个测试类工作正常,但是一旦我引入 mockStatic,测试类就会因检测失败而失败。

有没有人看到这个失败并知道任何解决方法?我无法更改静态成员变量。

【问题讨论】:

  • 我相信仪器需要在测试上完成,而不是类。至少在我的项目中,唯一被检测的是我的测试类,而我的其他类被排除在外。试试这个,如果它不起作用,请发布您的 pom/ant 文件,以便我再看一下。

标签: mockito powermock jacoco


【解决方案1】:

我终于弄清楚了我认为是什么问题。 Jacoco 检测将数据注入到您的字节码中,PowerMock 在尝试模拟静态时也会这样做。这会造成严重破坏,因为它们会互相踩踏,并且由于它们互相干扰,您会遇到非常奇怪的行为。我在不应该抛出 NPE 的代码中得到了各种各样的 NPE。

简单的解决方案是重构不必要的静态,并且知道如果您打算使用静态来控制数据流,如果您打算使用 Jacoco 进行覆盖,可能应该重新考虑测试架构。

您仍然可以在静力学上运行 Jacoco 检测,但不能同时模拟静力学;至少不是 PowerMock 和 Mockito 的方式。我不确定 EasyMock 是否会导致不同的行为,所以 ymmv。

【讨论】:

    【解决方案2】:

    我也遇到过类似的问题,但我相信有另一种解决方案,而不是必须重构静态数据。我在一个 maven pom 文件中做了这个,但我会解释发生了什么。 Jacoco 确实将数据注入到您的字节码中。是的,Powermock 使用了一个自定义的字节加载器,而 Jacoco 讨厌它。所以这里有一个解决方案来解决它。

    在您的 Jacoco 执行中,您需要 Jacoco 为您的测试使用默认工具。 (您可以指定 powermock 测试或只包括它以任何方式工作的所有测试)。下面是对默认仪器的解释:Offline-instrumentation with Jacoco

    然后您必须具有测试的恢复步骤。现在这是有趣的部分,您必须运行正常的 Jacoco Prepare Agent 步骤,同时排除在默认检测中运行的所有测试。 (如果你不这样做,你会收到一堆警告,比如 JaCoCo exceution data already exists for xTest)

    这将解决您的问题,并且您无需重构静态方法。虽然如果它们是不必要的,你可能还是应该把它们拿出来;)

     <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <version>${jacoco.version}</version>
                    <configuration>
                        <append>true</append>
                    </configuration>
                    <executions>
                        <execution>
                            <id>default-instrument</id>
                            <goals>
                                <goal>instrument</goal>
                            </goals>
                            <configuration>
                                <includes>
                                    <include>**/*test*</include>
                                </includes>
                            </configuration>
                        </execution>
                        <execution>
                            <id>default-restore-instrumented-classes</id>
                            <goals>
                                <goal>restore-instrumented-classes</goal>
                            </goals>
                            <configuration>
                                <includes>
                                    <include>**/*test*</include>
                                </includes>
                            </configuration>
                        </execution>
                        <execution>
                            <id>Prepare-Jacoco</id>
                            <goals>
                                <goal>prepare-agent</goal>
                            </goals>
                            <configuration>
                                <excludes>
                                    <exclude>**/*test*</exclude>
                                </excludes>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
    

    【讨论】:

      猜你喜欢
      • 2018-03-04
      • 2020-10-16
      • 1970-01-01
      • 2017-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-27
      • 1970-01-01
      相关资源
      最近更新 更多