java - 如何防止创建模拟对象来运行静态初始化?

标签 java junit mocking

给定这段代码:

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 at 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) at org.mockito.internal.creation.jmock.ClassImposterizer.createProxy(ClassImposterizer.java:128) at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:63) at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:56) at org.mockito.internal.creation.CglibMockMaker.createMock(CglibMockMaker.java:23) at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26) at org.mockito.internal.MockitoCore.mock(MockitoCore.java:51) at org.mockito.Mockito.mock(Mockito.java:1243) at org.mockito.Mockito.mock(Mockito.java:1120) at my.test.Class.testBooh(my.test.Class.java:162) ....

Caused by: java.lang.RuntimeException: 我没有看到那个来了 ...

简单的问题:有什么方法可以防止这种异常吗?不改变生产代码来避免静态初始化的事情?

( 上面的代码是 mcve;实际上,事情要复杂得多,但最终我们的问题是单元测试代码试图模拟一个类……这会导致大量的static 要初始化的 final ;以及一些初始化语句在我们的单元测试环境中抛出)。

郑重声明:这不是 Mokito 问题,我在使用 EasyMock 时遇到了同样的问题。

最佳答案

一种解决方案是使用 JMockit 模拟类:

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

(默认情况下,stubOutClassInitializationfalse,因为清除类的静态初始值设定项意味着任何 static final 字段将保持未初始化状态,直到测试运行结束,因为 JVM 只对每个加载的类执行静态初始化一次。)

除此之外,您必须使用其他一些字节码操作工具(AspectJ、JBoss AOP、JBoss Byteman)或修复在静态初始化期间失败的实际生产类。

关于java - 如何防止创建模拟对象来运行静态初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40545624/

相关文章:

java - 在 App Engine 中存储 BitSet

android - 无法在 Eclipse 中启动 Android JUnit 测试。停留在 : Launching: Creating source locator

javascript - 用 Jest 测试 setTimeout 上的毫秒参数

java - 如何让Timer类在Java中每10秒加载一个jfreechart?

java - 使用 java 从 Tomcat 的 server.xml 中查找上下文路径

java - 你如何在 drools 中激活规则流组

java - 即使预期结果正确,JUnit 测试也会失败

java - 如何在 Spring Boot 中为 Controller 编写单元测试

testing - 转到类型错误 : struct does not implement interface

java - 将随机值模拟到对象中