使用 MockStatic 的离线 Jacoco 导致重新检测异常
Offline Jacoco using MockStatic cause re-instrumentation exception
我运行正在使用 PowerMock 1.6.4 和所有最新版本(尽管是 JUnit 4.11)。
- 我使用 Jacoco Ant 任务只检测 classes,而不是测试 classes。我还使用 Jacoco ant 任务 运行 Junit 测试,然后生成报告。
现在我遇到了一个我想不通的问题...
- 我有一个测试 class 测试 class Foo 的一个成员函数。
- Foo 的一个成员是静态的,所以我将其包装在一个静态函数中,这样我就可以通过 mock 控制执行,但副作用是我现在需要 mockStatic。
我注意到 PowerMockito.mockStatic(Foo.class) ...所有测试都因仪器问题而失败。
我有另一个测试 class 测试 Foo 的另一个成员函数。这个测试 class 工作正常,但是一旦我引入 mockStatic,测试 class 就会因检测失败而失败。
有没有人看到过这种失败并知道任何解决方法?我无法更改静态成员变量。
我终于弄清楚了我认为的问题所在。 Jacoco 检测将数据注入字节码,PowerMock 在尝试模拟静态时也是如此。这会造成严重破坏,因为它们相互踩踏,而且由于它们相互干扰,你会得到非常奇怪的行为。我在代码中得到了一堆不应抛出 NPE 的 NPE。
简单的解决方案是重构不必要的静态,并且知道如果您计划使用静态来控制数据流,如果您计划使用 Jacoco 进行覆盖,可能应该重新考虑测试架构。
您仍然可以 运行 Jacoco 对静态进行检测,但不能同时模拟静态;至少不像 PowerMock with Mockito 那样。我不确定 EasyMock 是否会导致不同的行为,所以 ymmv.
我遇到了类似的问题,但我相信有另一种解决方案,而不是必须重构静力学。我在一个 maven pom 文件中做了这个,但我会解释发生了什么。 Jacoco 确实将数据注入到您的字节代码中。是的,Powermock 使用自定义字节加载器,而 Jacoco 讨厌它。所以这是解决它的解决方案。
在您的 Jacoco 执行中,您需要 Jacoco 为您的测试使用默认检测。 (您可以指定 powermock 测试或只包括它以任何一种方式工作的所有测试)。下面是对默认工具的解释:Offline-instrumentation with Jacoco。
然后您必须执行测试的还原步骤。现在是有趣的部分,您必须 运行 正常的 Jacoco Prepare Agent 步骤,同时排除所有在默认检测中 运行 的测试。 (如果你不这样做,你会收到一堆警告,比如 xTest 已经存在 JaCoCo 执行数据)
这将解决您的问题,您无需重构静态方法。虽然如果它们是不必要的,你可能还是应该把它们拿出来 ;)
<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>
我运行正在使用 PowerMock 1.6.4 和所有最新版本(尽管是 JUnit 4.11)。
- 我使用 Jacoco Ant 任务只检测 classes,而不是测试 classes。我还使用 Jacoco ant 任务 运行 Junit 测试,然后生成报告。
现在我遇到了一个我想不通的问题...
- 我有一个测试 class 测试 class Foo 的一个成员函数。
- Foo 的一个成员是静态的,所以我将其包装在一个静态函数中,这样我就可以通过 mock 控制执行,但副作用是我现在需要 mockStatic。
我注意到 PowerMockito.mockStatic(Foo.class) ...所有测试都因仪器问题而失败。
我有另一个测试 class 测试 Foo 的另一个成员函数。这个测试 class 工作正常,但是一旦我引入 mockStatic,测试 class 就会因检测失败而失败。
有没有人看到过这种失败并知道任何解决方法?我无法更改静态成员变量。
我终于弄清楚了我认为的问题所在。 Jacoco 检测将数据注入字节码,PowerMock 在尝试模拟静态时也是如此。这会造成严重破坏,因为它们相互踩踏,而且由于它们相互干扰,你会得到非常奇怪的行为。我在代码中得到了一堆不应抛出 NPE 的 NPE。
简单的解决方案是重构不必要的静态,并且知道如果您计划使用静态来控制数据流,如果您计划使用 Jacoco 进行覆盖,可能应该重新考虑测试架构。
您仍然可以 运行 Jacoco 对静态进行检测,但不能同时模拟静态;至少不像 PowerMock with Mockito 那样。我不确定 EasyMock 是否会导致不同的行为,所以 ymmv.
我遇到了类似的问题,但我相信有另一种解决方案,而不是必须重构静力学。我在一个 maven pom 文件中做了这个,但我会解释发生了什么。 Jacoco 确实将数据注入到您的字节代码中。是的,Powermock 使用自定义字节加载器,而 Jacoco 讨厌它。所以这是解决它的解决方案。
在您的 Jacoco 执行中,您需要 Jacoco 为您的测试使用默认检测。 (您可以指定 powermock 测试或只包括它以任何一种方式工作的所有测试)。下面是对默认工具的解释:Offline-instrumentation with Jacoco。
然后您必须执行测试的还原步骤。现在是有趣的部分,您必须 运行 正常的 Jacoco Prepare Agent 步骤,同时排除所有在默认检测中 运行 的测试。 (如果你不这样做,你会收到一堆警告,比如 xTest 已经存在 JaCoCo 执行数据)
这将解决您的问题,您无需重构静态方法。虽然如果它们是不必要的,你可能还是应该把它们拿出来 ;)
<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>