我们使用 maven 和 surefire 2.19 进行 Junit 4.11 测试。 当我们使用 IDE 或从命令行运行时,我们看不到任何故障。 然而,在使用 Jenkins 时,我们的一些测试会间歇性地失败验证静态断言。
下面是一个片段:
verifyStatic(times(1));
AClass.someStaticMethod(aUrl);
Surefire 有时会报告:
[java] Failed tests:
[java] AClass.someStaticMethod:55
[java] Wanted but not invoked AClass.someStaticMethod(
[java] "http://foo.com/artwork.png"
[java] );
[java] Actually, there were zero interactions with this mock.
我已经厌倦了在测试中单线程,认为这就是我们的 IDE 正在做的事情,但这没有帮助:
<reuseForks>false</reuseForks>
<forkCount>1</forkCount>
关于可能发生的情况以及如何解决它的任何建议?
更新:
在此测试运行之前,我调用 mockStatic(AClass.class)。
此外,我已经能够通过设置 while 循环在命令行上重现它。
while [ $? -eq 0 ]; do ./mvnvm -T 8 clean &&
./mvnvm -T 8 -b multithreaded -am -Dtest=AClassTests
-DfailIfNoTests=false -Dmaven.test.skip=false -pl MyProject test; done
最终在这个循环中,我会让测试失败。 现在,我必须弄清楚如何在故障发生之前检测故障并附加调试器。
更新 2:
我可以在 maven 清理后轻松重现此问题,似乎在清理后的第一次运行中发生。
对不起,我撒谎了。 Thread.sleep 对此没有影响。
更新 3:
根据更新2,Thread.sleep不起作用。
Arthor,这里有更多的代码:
PowerMockito.mockStatic(ImageUtil.class);
Mockito.when(ImageUtil.getImageDetail(imageUrl)).thenReturn(detail);
ValidationCommand command = new ValidationCommand();
command.execute(validationContext);
Thread.sleep(1000);
PowerMockito.verifyStatic(times(1));
ImageUtil.getImageDetail(imageUrl);
command.execute 将在正常执行期间调用 ImageUtil.getImageDetail 方法。
将以下代码添加到测试的开头:
PowerMockito.mockStatic(AClass.class);
无法告诉您问题实际上是什么;在将 surefire 从 2.17 升级到 2.18 时,我遇到了类似的问题。
不过,我也许可以提供一种解决方法:正如万无一失文档中所建议的那样,我在使用 PowerMockito 的测试中添加了@NotThreadSafe
- 这为我做到了。
不知何故,使用 powermock 的测试会遇到间歇性故障。虽然很难远离这些基于 CG lib 的模拟库,但我的团队只选择了 easymock,这在很大程度上降低了我们的生产力。