bootstrap 使用@Rule 的 PowerMock,但失败了

bootstrap PowerMock with @Rule ,but failed

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SessionUtil.class})
public class FundControllerTest {
     XXXXXXXXXXXXXXX.......
}

运行 Junit 如上,运行良好

但是当我尝试 运行 Junit 如下所示时,它失败了。因为我需要使用 Eclemma

覆盖我的测试,所以我切换到使用@Rule to bootstrap PowerMock,但失败了。请帮忙。

@PrepareForTest({ SessionUtil.class})
public class FundControllerTest {
    @Rule
    public PowerMockRule rule = new PowerMockRule();
    /*
    static{
        PowerMockAgent.initializeIfNeeded();
    }
    */
   XXXXXXXXXXXXXXXXXXXXXXXXX..........
}
java.lang.RuntimeException: com.sun.tools.attach.AttachNotSupportedException: Unable to enqueue operation: the target VM does not support attach mechanism
    at org.powermock.modules.agent.AgentLoader.getVirtualMachineImplementationFromEmbeddedOnes(AgentLoader.java:122)
    at org.powermock.modules.agent.AgentLoader.loadAgent(AgentLoader.java:81)
    at org.powermock.modules.agent.AgentInitialization.initializeAccordingToJDKVersion(AgentInitialization.java:40)
    at org.powermock.modules.agent.PowerMockAgent.initializeIfNeeded(PowerMockAgent.java:91)
    at com.hsbc.mf.frtend.twfunds.controller.FundControllerTest.<clinit>(FundControllerTest.java:53)
    at java.lang.J9VMInternals.initializeImpl(Native Method)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:199)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:56)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:39)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:527)
    at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)
    at org.junit.runners.BlockJUnit4ClassRunner.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:58)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: com.sun.tools.attach.AttachNotSupportedException: Unable to enqueue operation: the target VM does not support attach mechanism
    at sun.tools.attach.WindowsVirtualMachine.<init>(WindowsVirtualMachine.java:64)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:56)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:39)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:527)
    at org.powermock.reflect.internal.WhiteboxImpl.createInstance(WhiteboxImpl.java:1455)
    at org.powermock.reflect.internal.WhiteboxImpl.invokeConstructor(WhiteboxImpl.java:1303)
    at org.powermock.reflect.Whitebox.invokeConstructor(Whitebox.java:497)
    at org.powermock.modules.agent.AgentLoader.getVirtualMachineImplementationFromEmbeddedOnes(AgentLoader.java:120)
    ... 28 more

当你在床上发现一条蛇时,它是否从空旷的地方爬出来有关系window;还是从前门进来的?

换句话说:为了允许模拟 static 代码; PowerMock 需要操作 production class SessionUtils 的字节码。而 EclEmma 也依赖于字节码操作。

也许,在未来的某个时候,这两个框架的实现将一起工作(但是相应的 bug 已经快两年了;并且周围没有太多 activity ;所以不要屏住呼吸)。

但是今天,PowerMock 和 EclEmma 不能一起工作。故事结局。

并且 "pull in" PowerMock 使用自己的运行器并不重要;或使用 "rule approach"。因为如前所述:问题是你在床上发现了那条蛇;而不是 "how did it get there".

现在您只需要决定什么对您来说更重要:保持您的生产代码不变(及其设计,迫使您使用 PowerMock 模拟静态调用);或获取报道信息。

我个人的两分钱:这是我的团队完全放弃 PowerMock 的原因之一。相反,我们专注于编写无需模拟 static/new 调用即可测试的代码;猜猜看:效果很好。我们的生产代码比以前更好