2016-11-11 93 views
3

鑑於這種代碼:如何防止創建模擬對象來運行靜態inits?

class Booh { 
    final static Booh throwUp = new Booh(); 
    Booh() { throw new RuntimeException("I didn't see that one coming"); } 
} 

並採用Mokito.mock()測試:

@Test 
public void testBooh() { 
    Booh booh; 
    booh = mock(Booh.class); 
    } 
} 

我結束了:

java.lang.ExceptionInInitializerError 在java中。 lang.J9VMInternals.ensureError(J9VMInternals.java:137) at java.lang.J9VMInternals.recordInitializationFailure(J9VMInternals.java:126) at sun.reflect.GeneratedSerializationConstructorAccessor12.newInstance(Unknown Source) at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:56 ) 在org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73) 在org.mockito.internal.creation.jmock.ClassImposterizer.createProxy(ClassImposterizer.java:128) 在org.mockito.internal.creation.jmock .ClassImposterizer.imposterise(ClassImposterizer.java:63) 在org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:56) 在org.mockito.internal.creation.CglibMockMaker.createMock(CglibMockMaker.java :23) at org.mockito。在org.mockito.Mockito.mock(Mockito.java:1243) 處的org.mockito.internal.MockitoCore.mock(MockitoCore.java:51) org.mockito.Mockito.mock(Mockito.java:1120) 在my.test.Class.testBooh(my.test.Class.java:162) ....

所致:JAVA。 lang.RuntimeException:我沒有看到一個即將來臨 ...

簡單的問題:有什麼辦法如何我可以防止這種異常;而不更改生產代碼以避免靜態初始化事件?

(上面的代碼是一個mcve;事實上,事情更復雜,但最終我們的問題是單元測試代碼試圖模擬一個類...並導致大量的靜態決賽被初始化;一些init語句在我們的單元測試環境中拋出)。

備案:這不是Mokito問題,我使用EasyMock遇到同樣的問題。

+0

查看我的更新 - 即使在**嘲笑步驟之前聲明Booh **,mock()調用行也會引發異常。 – GhostCat

+0

我不確定我是否理解這個問題:不管嘲笑,你根本無法加載該課程。那麼它如何用於生產代碼呢?或者,你在問如何阻止你能夠嘲笑它嗎? –

+0

'Booh booh;'不會導致課程被加載。在'mock'行之前嘗試'System.out.println(Booh.throwUp);''。 –

回答

2

一種解決方案是與JMockit嘲笑類:

@Test 
public void testBooh(@Mocked(stubOutClassInitialization = true) Booh booh) { 
    ... 
} 

(默認情況下,stubOutClassInitializationfalse因爲磕碰列一類的靜態初始化指任何static final字段將保持未初始化,直到試驗結束運行,因爲JVM只執行靜態初始化一次每加載的類。)

除此之外,你要麼必須使用一些其他的字節碼操作工具(AspectJ中,JBoss的AOP,JBoss的Byteman)或修復ACTU在靜態初始化期間失敗的生產類。