PowerMockito:java.lang.NoClassDefFoundError

PowerMockito: java.lang.NoClassDefFoundError

我需要在我的 Junit 测试中模拟静态最终 class:

private MyFinalClient client;

@Before
public void setup() {

    // set up mock
    client = PowerMockito.mock(MyFinalClient.class);
    service = new PatientLocationService();
    service.setClient(client);
}

当我运行测试时我会得到以下错误信息:

java.lang.NoClassDefFoundError: Could not initialize class MyFinalClient$$EnhancerByMockitoWithCGLIB$bb8ec03
at sun.reflect.GeneratedSerializationConstructorAccessor6.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:45)
at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
at org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:14)
at org.powermock.api.mockito.repackaged.ClassImposterizer.createProxy(ClassImposterizer.java:143)
at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:58)
at org.powermock.api.mockito.internal.mockcreation.MockCreator.createMethodInvocationControl(MockCreator.java:110)
at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:58)
at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:143)
at com.hihi.ohyeahServiceTest.setup(ohyeahServiceTest.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:132)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:95)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

不完全确定为什么我会得到这个...如果我在 Spring Tool Suite 中执行此操作不会产生任何错误,但会在命令提示符和 IntelliJ 中中断(在正常的 eclipse 中也是如此)

请帮忙!

谢谢!

编辑: 这是 powermock 信息:

<dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito</artifactId>
        <version>1.6.2</version>
        <scope>test</scope>
    </dependency>

我正在使用 spring 启动启动器测试,从 class 路径我可以看到我正在使用:

我通过 import->existing Maven 项目导入了项目(通过包含 pom.xml),在 Idea 中我也在做类似的事情...

我认为您可能遗漏了一些测试引导程序 class。你的测试用例有这样的注释吗class?

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyFinalClient.class)

这将使 powermock 准备 MyFinalClient class 一些字节码操作,以便它可以正确生成模拟。

我还注意到在 JVM 8 下做这样的事情时有些奇怪,字节码验证器会在您的测试运行时抱怨。您可以通过在测试时将“-noverify”标志添加到您的 jvmargs 来解决这个问题。

只是想提供一些发现,希望对其他遇到同样情况的人有所帮助。

深入研究后,如果 class 之前已加载,junit class 加载程序似乎在加载 class 时会出现问题。在我的例子中,我的控制器测试会 运行 拳头,服务测试会在之后进行。 运行 两者一起会导致上面列出的 no class def found 异常。注释掉控制器测试时,junit 测试可以正常工作。这就证明测试本身没问题。

我还没有找到处理这种情况的方法,可能的处理方法是将服务和控制器分成 2 个项目,这样单元测试就不会 运行 在一起。