Получено ExceptionInInitializerError, когда имитирующий конструктор класса с Powermock.Как это исправить? - PullRequest
7 голосов
/ 29 сентября 2011

Вот мой случай. У меня есть класс AbstractController. У него есть подкласс Controller. В одном из методов AbstractController создается новый ApplicationLock. Я хотел бы издеваться над ApplicationLock при написании ut для контроллера. Я написал тестовый пример, как показано ниже.

@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);
}

Я добавил необходимые аннотации в тестовый класс.

@ RunWith (PowerMockRunner.class)

@ PrepareForTest ({AbstractController.class})

Но я получил следующую ошибку при запуске этого теста. Это статический инициализатор в AbstractController.

Вызывается: java.lang.NullPointerException на com.acompany.controller.common.AbstractController. (AbstractController.java:65)

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

Полная трассировка стека, как показано ниже.

java.lang.ExceptionInInitializerError at java.lang.Class.forName0 (собственный метод) в java.lang.Class.forName (Class.java:169) в javassist.runtime.Desc.getClassObject (Desc.java:44) в javassist.runtime.Desc.getClassType (Desc.java:153) в javassist.runtime.Desc.getType (Desc.java:123) в javassist.runtime.Desc.getType (Desc.java:79) в com.acompany.controller.portfolio.ControllerTest.testIncrementalFail (ControllerTest.java:195) в sun.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод) в sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) в java.lang.reflect.Method.invoke (Method.java:597) в org.junit.internal.runners.TestMethod.invoke (TestMethod.java:66) в org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.runTestMethod (PowerMockJUnit44RunnerDelegateImpl.java:307) в org.junit.internal.runners.MethodRoadie $ 2.run (MethodRoadie.java:86) в org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters (MethodRoadie.java:94) в org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.executeTest (PowerMockJUnit44RunnerDelegateImpl.java:294) в org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTestInSuper (PowerMockJUnit47RunnerDelegateImpl.java:112) в org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTest (PowerMockJUnit47RunnerDelegateImpl.java:73) в org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters (PowerMockJUnit44RunnerDelegateImpl.java:282) в org.junit.internal.runners.MethodRoadie.runTest (MethodRoadie.java:84) в org.junit.internal.runners.MethodRoadie.run (MethodRoadie.java:49) в org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod (PowerMockJUnit44RunnerDelegateImpl.java:207) в org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods (PowerMockJUnit44RunnerDelegateImpl.java:146) в org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ 1.run (PowerMockJUnit44RunnerDelegateImpl.java:120) в org.junit.internal.runners.ClassRoadie.runUnprotected (ClassRoadie.java:34) в org.junit.internal.runners.ClassRoadie.runProtected (ClassRoadie.java:44) в org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run (PowerMockJUnit44RunnerDelegateImpl.java:118) в org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run (JUnit4TestSuiteChunkerImpl.java:102) в org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run (AbstractCommonPowerMockRunner.java:53) в org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run (JUnit4TestReference.java:49) вorg.eclipse.jdt.internal.junit.runner.TestExecution.run (TestExecution.java:38) в org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:467lg. org.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:683) в org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run (RemoteTestRunner.java:390) в org.ec.junit.runner.RemoteTestRunner.main (RemoteTestRunner.java:197) Вызывается: java.lang.NullPointerException в com.acompany.controller.common.AbstractController. (AbstractController.java:65) ... еще 35

1 Ответ

3 голосов
/ 30 сентября 2011

Тогда вы можете использовать:

 @SuppressStaticInitializationFor({AbstractController.class})

И затем, в вашем тестовом примере, вручную установить все статические поля, которые необходимо инициализировать, включая DEFAULT_FOLDER:

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

метод Class<?>.getProtectionDomain() слишком сильно зависит от используемого загрузчика классов, так что вы, вероятно, не сможете заставить его работать в JUnit / PowerMock, которые используют свои собственные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...