3

I have a enum MyEnum.java which has one static method.

//MyEnum.java

enum MyEnum {

  ONE("one"),
  TWO("two");

  private String value;
  MyEnum(String value){
    this.value=value;
  }

  public static MyEnum getMyEnum(String value){
    for(MyEnum myEnum : MyEnum.values()){
      if(myEnum.value.equalsIgnoreCase(value))
      return myEnum;
    }
    return null;
  }
}

I am using PowerMock to mock static methods of this enum. I have included all the necessary conditions like

@Runwith(PowerMockRunner.class)
@PrepareForTest(MyEnum.class)

//Test function
PowerMockito.mockStatic(MyEnum.class);

It all works fine. But if I am using switch method for the object of enum, then it throws the exception.

MyEnum enum = MyEnum.ONE;
switch(enum){
case ONE:
break
}

This code is throwing the following exception.

    java.lang.ExceptionInInitializerError
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:191)
    at javassist.runtime.Desc.getClassObject(Desc.java:43)
    at javassist.runtime.Desc.getClazz(Desc.java:52)
    at com.newshunt.shared.presenters.tests.DummyTest.testStaticMethod(DummyTest.java:26)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
    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:87)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
    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:34)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
    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:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.NullPointerException
    at com.newshunt.shared.presenters.tests.DummyTest$1.<clinit>(DummyTest.java:26)
    ... 37 more


Process finished with exit code -1

Even from the logs it is not clear, what is causing this exception to happen? Anybody else encountered similar issues before ?

thedarkpassenger
  • 7,158
  • 3
  • 37
  • 61

1 Answers1

1

My recommendation: consider not using PowerMock.

PowerMock looks like the solution to many problems; but rather sooner than later, it can be the cause of much more problems. It breaks coverage, it makes it harder to change the underlying JVM, and so on.

Seriously: if your design can only be tested with PowerMock, this is very often a clear indication that your design is bad. So: focus on reworking your code under test!

In your case: I would start questioning the need of having a static method on an enum. So, in other words: what is the problem you want to address with this code?

But to answer the actual question: you have to understand that enum constants are represented as inner classes themselves. Therefore you have to use the fullyQualifiedName property for @PrepareForTest. See this newer question for an example.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • well clearly, I agree with your solution. We are working on rewriting our code so that it is more testing friendly.But there are some legacy classes which we don't want to disturb at this point. And the static method in the enum class is to return the enum based on its value. – thedarkpassenger May 18 '16 at 10:56
  • I don't get what you mean: "return the enum based on its value". Maybe you want to update your question; or we pull this into a discussion ... – GhostCat May 18 '16 at 11:02
  • I see. Looking at that ... are you sure you have to put that method **into** the enum? – GhostCat May 18 '16 at 11:14
  • what do you suggest here? Creating a utility/helper class and put this function as a non-static method ? – thedarkpassenger May 18 '16 at 11:30
  • For example; and if you need "quick access"; you can put that method on some "other" singleton enum. – GhostCat May 18 '16 at 11:51