Java 如何防止创建模拟对象来运行静态初始化?
鉴于此代码:Java 如何防止创建模拟对象来运行静态初始化?,java,junit,mocking,Java,Junit,Mocking,鉴于此代码: class Booh { final static Booh throwUp = new Booh(); Booh() { throw new RuntimeException("I didn't see that one coming"); } } 以及使用Mokito.mock()的测试: 我的结局是: java.lang.ExceptionInInitializeError 在java.lang.J9VMInternals.ensureError(J9VMInter
class Booh {
final static Booh throwUp = new Booh();
Booh() { throw new RuntimeException("I didn't see that one coming"); }
}
以及使用Mokito.mock()的测试:
我的结局是:
java.lang.ExceptionInInitializeError
在java.lang.J9VMInternals.ensureError(J9VMInternals.java:137)
在java.lang.J9VMInternals.recordInitializationFailure(J9VMInternals.java:126)中
位于sun.reflect.GeneratedSerializationConstructorAccessor12.newInstance(未知源)
位于java.lang.reflect.Constructor.newInstance(Constructor.java:436)
位于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.importerise(ClassImposterizer.java:63)
位于org.mockito.internal.creation.jmock.ClassImposterizer.importise(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)
在my.test.Class.testBooh(my.test.Class.java:162)
原因:java.lang.RuntimeException:我没看到会发生这样的情况
简单的问题:我有什么方法可以防止这种例外;不改变生产代码来避免静态初始化
(上面的代码是一个mcve;事实上,事情更加复杂,但最终我们的问题是单元测试代码试图模拟一个类……这导致大量的静态期末考试被初始化;一些init语句出现在我们的单元测试环境中)
作为记录:这不是一个Mokito问题,例如,我使用EasyMock遇到了相同的问题 一种解决方案是使用JMockit模拟类:
@Test
public void testBooh(@Mocked(stubOutClassInitialization = true) Booh booh) {
...
}
(默认情况下,stubOutClassInitialization
为false
,因为去掉类的静态初始值设定项意味着任何static final
字段都将保持未初始化状态,直到测试运行结束,因为JVM只对每个加载的类执行一次静态初始化。)
除此之外,您还必须使用其他字节码操作工具(AspectJ、JBoss AOP、JBoss Byteman)或修复在静态初始化过程中失败的实际生产类。查看我的更新-即使在模拟步骤之前声明Booh,也会为mock()引发异常电话线。我不确定我是否理解这个问题:你根本不能加载那个类,不管有没有嘲笑。那么如何在生产代码中使用它呢?或者,你是在问如何阻止你嘲笑它代码>不会导致类被加载。尝试
System.out.println(Booh.throwUp)代码>在mock
行之前。显然在PowerMock中有一个注释@SuppressStaticInitializationFor(classname)
。也许这能帮你?另请参阅并回答。@QBrute可能会有所帮助,但我们这里有一个严格的“无powermock”政策。
@Test
public void testBooh(@Mocked(stubOutClassInitialization = true) Booh booh) {
...
}