2016-11-11 72 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在静态初始化期间失败的生产类。