鉴于此代码:
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 java.lang.reflect.Constructor.newInstance(Constructor.java:436) at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:56) at 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) 在org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26) 在org.mockito.internal.MockitoCore.mock(MockitoCore.java:51) 在org.mockito.Mockito.mock(Mockito.java:1243) 在org.mockito.Mockito.mock(Mockito.java:1120) at my.test.Class.testBooh(my.test.Class.java:162) ....
引起:java.lang.RuntimeException:我没看到那个人来了 ...
简单的问题:有什么方法可以防止这种异常;不改变生产代码以避免那个静态初始化的东西?
(上面的代码是一个mcve;实际上,事情更复杂,但最终我们的问题是单元测试代码试图模拟一个类......这会导致大量的静态结束初始化;以及一些初始语句在我们的单元测试环境中抛出。)
为了记录:这不是Mokito问题,我使用EasyMock遇到了同样的问题。
答案 0 :(得分:3)
一种解决方案是使用JMockit模拟类:
@Test
public void testBooh(@Mocked(stubOutClassInitialization = true) Booh booh) {
...
}
(默认情况下,stubOutClassInitialization
为false
,因为删除类的静态初始化程序意味着任何static final
字段在测试运行结束前将保持未初始化状态,因为仅限JVM每个加载的类执行静态初始化一次。)
除此之外,您还必须使用其他字节码操作工具(AspectJ,JBoss AOP,JBoss Byteman)或修复在静态初始化期间失败的实际生产类。