2011-09-29 74 views
6

这是我的情况。我有一个AbstractController类。它有一个子类控制器。在一个AbstractController的方法中,一个新的ApplicationLock被实例化。编写控制器的ut时,我想模拟ApplicationLock。我写了一个像下面这样的测试用例。使用Powermock模拟类的构造函数时发生ExceptionInInitializerError。如何解决它?

@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显示java.lang.NullPointerException (AbstractController.java:65)

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

完整堆栈跟踪如下所示。

java.lang.ExceptionInInitializerError处 javassist.runtime.Desc.getClassObject java.lang.Class.forName0(本机方法)在 java.lang.Class.forName(Class.java:169)( Desc.java:44)在 javassist.runtime.Desc.getClassType(Desc.java:153)处 javassist.runtime.Desc.getType javassist.runtime.Desc.getType(Desc.java:123)(图示的java:79)在在 sun.reflect.NativeMethodAccessorImpl com.acompany.controller.portfolio.ControllerTest.testIncrementalFail(ControllerTest.java:195) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)。调用(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.PowerMockJUn it44RunnerDelegateImpl $ 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) a t 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) 在 或g.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: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) 引起:java.lang.NullPointerException在 com.acompany.controller.common.AbstractController。(AbstractController.java: 65) ...... 35多个

回答

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中工作。

+0

谢谢。我试过了。但是我无法抑制AbstractController中的所有静态初始化器。如果我这样做,我会得到空指针。 – Smartmarkey

+0

@Smartmarkey另一个想法发生在我身上。 – MaDa

相关问题