2011-09-29 16 views
6

Đây là trường hợp của tôi. Tôi có một lớp AbstractController. Nó có một bộ điều khiển lớp con. Trong một trong các phương thức của AbstractController, một ApplicationLock mới được khởi tạo. Tôi muốn giả lập ApplicationLock khi viết ut cho Controller. Tôi đã viết một trường hợp thử nghiệm như dưới đây.Có ExceptionInInitializerError khi xây dựng mô phỏng của một lớp với Powermock. Làm thế nào để sửa chữa nó?

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

Tôi đã thêm chú thích cần thiết vào lớp kiểm tra.

@RunWith (PowerMockRunner.class)

@PrepareForTest ({} AbstractController.class)

Nhưng tôi đã nhận lỗi sau khi chạy test này. Đó là khởi tạo tĩnh trong AbstractController.

Nguyên nhân:. Java.lang.NullPointerException tại com.acompany.controller.common.AbstractController (AbstractController.java:65)

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

Full stack trace là như dưới đây.

java.lang.ExceptionInInitializerError tại java.lang.Class.forName0 (Native Method) tại java.lang.Class.forName (Class.java:169) tại javassist.runtime.Desc.getClassObject (Desc.java:44) tại javassist.runtime.Desc.getClassType (Desc.java:153) tại javassist.runtime.Desc.getType (Desc.java:123) tại javassist.runtime.Desc.getType (Desc. java: 79) tại com.acompany.controller.portfolio.ControllerTest.testIncrementalFail (ControllerTest.java:195) tại sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method) tại sun.reflect.NativeMethodAccessorImpl. gọi (NativeMethodAccessorImpl.java:39) tại sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) tại java.lang.reflect.Method.invoke (Method.java:597) tại org.junit.internal .runners.TestMethod.invoke (TestMethod.java:66) tại org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.runTestMethod (PowerMockJUnit44RunnerDelegateImpl.java:307) tại org.junit.internal.runners. MethodRoadie $ 2.run (MethodRoadie.java:86) tại org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters (MethodRoadie.java:94) tại org.powermock.modules.junit4.internal.impl.PowerMockJUn it44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.executeTest (PowerMockJUnit44RunnerDelegateImpl.java:294) tại org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTestInSuper (PowerMockJUnit47RunnerDelegateImpl.java:112) tại org.powermock.modules.junit4. internal.impl.PowerMockJUnit47RunnerDelegateImpl $ PowerMockJUnit47MethodRunner.executeTest (PowerMockJUnit47RunnerDelegateImpl.java:73) tại org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters (PowerMockJUnit44RunnerDelegateImpl.java:282) tại org.junit. internal.runners.MethodRoadie.runTest (MethodRoadie.java:84) a t org.junit.internal.runners.MethodRoadie.run (MethodRoadie.java:49) tại org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod (PowerMockJUnit44RunnerDelegateImpl.java:207) tại org.powermock.modules.junit4.internal.impl. PowerMockJUnit44RunnerDelegateImpl.runMethods (PowerMockJUnit44RunnerDelegateImpl.java:146) tại org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl $ 1.run (PowerMockJUnit44RunnerDelegateImpl.java:120) tại org.junit.internal.runners.ClassRoadie.runUnprotected (ClassRoadie.java:34) tại org.junit.internal.runners.ClassRoadie.runProtected (ClassRoadie.java:44) tại hoặc g.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run (PowerMockJUnit44RunnerDelegateImpl.java:118) tại org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run (JUnit4TestSuiteChunkerImpl.java:102) tại org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run (AbstractCommonPowerMockRunner.java:53) tại org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run (JUnit4TestReference.java:49) tại org.eclipse.jdt.internal.junit.runner.TestExecution.run (TestExecution.java:38) tại org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:467) tại org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:683) tại org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run (RemoteTestRunner.java:390) tại org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main (RemoteTestRunner.java:197) Gây ra bởi: java.lang.NullPointerException tại com.acompany.controller.common.AbstractController. (AbstractController.java: 65) ... 35 hơn

Trả lời

3

Bạn có thể sử dụng sau đó:

@SuppressStaticInitializationFor({AbstractController.class}) 

Và sau đó, trong trường hợp thử nghiệm của bạn, cài đặt thủ công trên mọi lĩnh vực tĩnh mà cần phải được khởi tạo, trong đó có DEFAULT_FOLDER:

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

Phương pháp Class<?>.getProtectionDomain() phụ thuộc quá nhiều vào lớp bộ nạp được sử dụng, vì vậy bạn có thể sẽ không làm cho nó hoạt động trong JUnit/PowerMock, sử dụng riêng của họ.

+0

Cảm ơn. Tôi đã thử nó. Nhưng tôi không thể ngăn chặn tất cả các initializers tĩnh trong AbstractController. Tôi sẽ nhận được con trỏ null nếu tôi làm như vậy. – Smartmarkey

+0

@Smartmarkey Một ý tưởng khác xảy ra với tôi. – MaDa