8

这是我的情况。我有一个 AbstractController 类。它有一个子类Controller。在 AbstractController 的一种方法中,实例化了一个新的 ApplicationLock。在为 Controller 编写 ut 时,我想模拟 ApplicationLock。我写了一个如下所示的测试用例。

@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 中的静态初始化程序。

引起:com.acompany.controller.common.AbstractController.(AbstractController.java:65) 处的 java.lang.NullPointerException

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

完整的堆栈跟踪如下。

java.lang.ExceptionInInitializerError 在 java.lang.Class.forName0(Native Method) 在 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(Native Method) 在 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) at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86) at org.junit.internal.runners.MethodRoadie .runBeforesThenTestThenAfters(MethodRoadie.java:94) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMethodRunner .executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:112) 在 org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:73) 在 org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84) 的 org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84) .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) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120) at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.爪哇: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) at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) at 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:467) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 在 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)引起:com.acompany.controller.common.AbstractController.(AbstractController.java:65) 处的 java.lang.NullPointerException ... 35 更多

4

1 回答 1

3

你可以使用:

 @SuppressStaticInitializationFor({AbstractController.class})

然后,在您的测试用例中,手动设置所有需要初始化的静态字段,包​​括 DEFAULT_FOLDER:

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

该方法Class<?>.getProtectionDomain()过多地依赖于使用的类加载器,因此您可能无法在使用自己的 JUnit/PowerMock 中使用它。

于 2011-09-30T11:19:57.030 回答