使用@Rule引导PowerMock,但失败了

时间:2017-03-31 03:10:43

标签: junit mocking powermock

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

如上所述运行Junit,效果很好。

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

覆盖我的测试,所以我切换到使用@Rule来引导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$1.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$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.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

1 个答案:

答案 0 :(得分:1)

当你在床上发现一条蛇时,它是否爬过敞开的窗户是否重要;还是来自前门?

换句话说:为了允许模拟静态代码; PowerMock需要操作生产类SessionUtils的字节代码。 EclEmma还依赖于字节码操作。

也许,在未来的某个时刻,两个框架的实现将一起工作(但相应的bug已经差不多两年了;并且围绕它没有太多活动;所以不要屏住呼吸在上面)。

但是今天,PowerMock和EclEmma并没有合作。故事结局。

使用自己的跑步者“拉入”PowerMock并不重要;或使用“规则方法”。因为如上所述:问题是你在床上发现了蛇;而不是“它是如何到达那里的”。

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

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