4

I need to mock a static final class in my Junit test:

private MyFinalClient client;

@Before
public void setup() {

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

When I run the test I will get the following error message:

java.lang.NoClassDefFoundError: Could not initialize class MyFinalClient$$EnhancerByMockitoWithCGLIB$$7bb8ec03
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$1.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)

Not entirely sure why I am getting this... This will not generate any error if I do this in Spring Tool Suite but will break on command prompt and in IntelliJ (in normal eclipse as well)

Please help!

Thanks!

edit: Here is the powermock info:

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

I am using spring boot starter test and from class path i can see i am using:

  • mockito-all-1.9.5
  • mockito-core-1.10.19

I imported the project via import->existing Maven project (by including the pom.xml) where in Idea I am doing similar things as well...

Richard Hsu
  • 843
  • 1
  • 10
  • 15

2 Answers2

1

I think you might be missing some bootstrapping of your test class. Do you have annotations on your test case class like this?

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

That'll get powermock to prepare the MyFinalClient class with some bytecode manipulation so that it can properly generate the mock.

I've also noticed some weirdness under JVM 8 when doing things like this where the byte code verifier will complain when your test runs. You can get around that by adding the '-noverify' flag to your jvmargs at test.

David
  • 2,602
  • 1
  • 18
  • 32
  • I did included the RunWith and PrepareForTest, I am able to run the test in STS but not in Idea, command prompt and normal eclipse; adding "-noverify" does not prevent it from failing... – Richard Hsu Sep 23 '15 at 17:32
1

Just want to provide some findings, hopefully it would help others when seeing the same situation.

After digging deeper into it, it seems like junit class loader would have problem loading class if the class has been loaded previously. In my case, my controller test would run fist, services test would came afterwards. Running both together would cause the no class def found exception listed above. When commenting out controller test, the junit test would work without any problem. This proves that the test itself is fine.

I still have not figure out a way to deal with this situation, potential way of dealing with this is to separate service and controller into 2 projects so the unit test don't run together.

Richard Hsu
  • 843
  • 1
  • 10
  • 15