Got ExceptionInInitializerError on mocking class constructor with Powermock. How to fix it?

Here is my case. I have an AbstractController class. It has a subclass controller. In one of the AbstractController methods, an instance of the new ApplicationLock is created. I would like to make fun of ApplicationLock when writing ut for Controller. I wrote a test case as shown below.

@test public void testMethod(){ ApplicationLock mockLock=PowerMockito.mock(ApplicationLock.class); PowerMockito.when(mockLock.tryObtain()).thenReturn(true); PowerMockito.whenNew(ApplicationLock.class).withArguments(argThat(new IsFile()),anyString()).thenReturn(mockLock); } 

I added the necessary annotations to the test class.

@RunWith (PowerMockRunner.class)

@PrepareForTest ({AbstractController.class})

But when running this test, I got the following error. This is a static initializer in AbstractController.

Called: java.lang.NullPointerException on com.acompany.controller.common.AbstractController. (AbstractController.java:65)

 private static final String DEFAULT_FOLDER = AbstractController.class.getProtectionDomain().getCodeSource() .getLocation().getPath(); 

A full stack trace is as follows.

java.lang.ExceptionInInitializerError at java.lang.Class.forName0 (Native method) in java.lang.Class.forName (Class.java:169) in javassist.runtime.Desc.getClassObject (Desc.java:44) in javassist. runtime.Desc.getClassType (Desc.java:153) at javassist.runtime.Desc.getType (Desc.java:123) at javassist.runtime.Desc.getType (Desc.java:79) at com.acompany.controller.portfolio .ControllerTest.testIncrementalFail (ControllerTest.java:195) at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) in sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java : 25) in java.lang.reflect.Method.invoke (Method.java∗97) in org.junit.internal.runners.TestMethod.invoke (TestMethod.java:66) in org.powermock.modules.junit4.internal. impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.runTestMethod (PowerMockJUnit44RunnerDelegateImpl.java:307) in org.junit .internal.runners.MethodRoadie $ 2.run (MethodRoadie.java:86) in org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters (MethodRoadie.java:94) in org.powermock.modules.junit4.internal.implnnerpunplunnerplunnerplimnerpunplunnerplimnerpowerplanner PowerMockJUnit44MethodRunner.executeTest (PowerMockJUnit44RunnerDelegateImpl.java:294) in org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTestInSuper (PowerMockJUnit47RunnerDelegateImpl.java:112) in org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTest (PowerMockJUnit47RunnerDelegateImpl.java:73) in org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters (PowerMockJUnit44RunnerDelegateImpl.java:282) in org.junit.internal.runners.MethodRoadie.runTest (MethodRoadie. java: 84) on org.junit.internal.runners.MethodRoadie.run (MethodRoadie.ja va: 49) in org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod (PowerMockJUnit44RunnerDelegateImpl.java:207) in org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods (PowerMockJUnit44RunnerDelegateImpl.java:146) in org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ 1.run (PowerMockJUnit44RunnerDelegateImpl.java:120) in org.junit.internal.runners.ClassRoadie.runUnprotected. Classunload.runUnprotected. classunun.jun runners.ClassRoadie.runProtected (ClassRoadie.java:44) in org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run (PowerMockJUnit44RunnerDelegateImpl.java:118) in orgmodim.powermun.plm.powermun.plomm.powermun.plommun.plomm.powermun.plomm.powermun JUnit4TestSuiteChunkerImpl.run (JUnit4TestSuiteChunkerImpl.java:102) at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run (AbstractCommonPowerMockRunner.jeclternal.org it4.runner.JUnit4TestReference.run (JUnit4TestReference.java:49) in org.eclipse.jdt.internal.junit.runner.TestExecution.run (TestExecution.java:38) in org.eclipse.jdt.internal.junit.runner. RemoteTestRunner.runTests (RemoteTestRunner.javarige67) in org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:683) in org.eclipse.jdt.internal.junit.runestRrnernerunner RemoteTestRunner. (AbstractController.java:65) ... 35 more info

+6
source share
1 answer

You can use then:

  @SuppressStaticInitializationFor({AbstractController.class}) 

And then in the test case, manually set all the static fields that you want to initialize, including DEFAULT_FOLDER:

 Whitebox.setInternalState(Controller.class, "DEFAULT_FOLDER", "abcd"); Whitebox.setInternalState(Controller.class, "OTHER_FIELD", new Object()); 

The Class<?>.getProtectionDomain() method is too much dependent on the classloader used, so you probably cannot use it in JUnit / PowerMock, which use their own.

+3
source

Source: https://habr.com/ru/post/898253/


All Articles