JUnit4测试中Mock含静态成员的ClassToMock类以避免初始化异常
问题解答
能否直接Mock ClassToMock类?
不能。ClassToMock的静态成员staticMember_是在类加载阶段执行初始化的,当你尝试调用mock(ClassToMock.class)时,JVM会先加载该类,触发new StaticMemberDeserializer().deserialize()的执行,此时会直接抛出ExceptionInInitializerError,根本无法执行后续的Mock代码。你当前使用的whenNew仅针对类的构造方法,和静态成员初始化逻辑无关,因此起不到作用。
解决异常的可行方案
方案1:抑制ClassToMock的静态初始化
使用PowerMock的@SuppressStaticInitializationFor注解跳过类的静态初始化逻辑,从根源避免初始化时的异常。
实现步骤:
- 测试类添加PowerMock运行器和准备注解
- 通过指定类全路径抑制其静态初始化
- 正常Mock目标类
代码示例:
@RunWith(PowerMockRunner.class) @PrepareForTest(ClassToMock.class) // 替换为ClassToMock实际的包名+类名 @SuppressStaticInitializationFor("com.yourpkg.ClassToMock") public class TargetTest { @Test public void testCase() { // 此时可正常Mock ClassToMock ClassToMock mockInstance = mock(ClassToMock.class); // 编写测试逻辑 } }
方案2:Mock StaticMemberDeserializer的deserialize方法
如果需要保留ClassToMock的其他静态逻辑,可通过MockStaticMemberDeserializer的实例和deserialize方法,让静态成员初始化时获取Mock对象,避免异常。
实现步骤:
- 测试类添加PowerMock运行器,并将
ClassToMock和StaticMemberDeserializer都加入准备列表 - 在测试前置方法中,Mock
StaticMemberDeserializer的实例及deserialize方法的返回值 - 确保Mock逻辑在
ClassToMock加载前执行
代码示例:
@RunWith(PowerMockRunner.class) @PrepareForTest({ClassToMock.class, StaticMemberDeserializer.class}) public class TargetTest { @Before public void setup() throws Exception { // Mock StaticMember实例 StaticMember staticMemberMock = mock(StaticMember.class); // Mock StaticMemberDeserializer实例 StaticMemberDeserializer deserializerMock = mock(StaticMemberDeserializer.class); // 让new StaticMemberDeserializer()返回Mock实例 PowerMockito.whenNew(StaticMemberDeserializer.class).withNoArguments().thenReturn(deserializerMock); // 让deserialize方法返回Mock的StaticMember PowerMockito.when(deserializerMock.deserialize(anyString())).thenReturn(staticMemberMock); } @Test public void testCase() { // ClassToMock加载时,staticMember_会被初始化为Mock对象,无异常抛出 // 可正常使用或Mock ClassToMock } }
注意事项
- 确保PowerMock与JUnit4版本兼容,避免依赖冲突
- 若
StaticMemberDeserializer是final类,必须将其加入@PrepareForTest列表才能被Mock - 方案1适合无需保留静态初始化逻辑的场景,方案2适合需要部分保留静态逻辑的场景
内容的提问来源于stack exchange,提问作者Satyam Poddar
相关产品推荐
相关产品推荐

