JDK17适配Mockito4.9.0后,如何替代@SuppressStaticInitializationFor?
Mockito 4.X 替代@SuppressStaticInitializationFor的方案
问题背景
报错信息:
Cannot instrument class XXX because it or one of its supertypes could not be initialized
因JDK17兼容性问题切换至Mockito 4.9.0后,原@SuppressStaticInitializationFor注解无法使用,但需要阻止部分类的静态初始化逻辑执行,现有测试代码如下:
@RunWith(MockitoJUnitRunner.class) //@PrepareForTest({NonWorkingDayHelper.class, TaskService.class}) //@SuppressStaticInitializationFor("com.ecquaria.cloud.entity.nonworkingday.NonWorkingDayHelper") public class TaskManagerTest { @Before public void setUp(){ Mockito.mockStatic(NonWorkingDayHelper.class); Mockito.mockStatic(TaskService.class); } @Test public void testUpdateSLARemainInDays() throws Exception { Mockito.when(NonWorkingDayHelper.isNonWorkingDay(any(Date.class))).thenReturn(false); Mockito.when(TaskService.getInstance()).thenReturn(Mockito.mock(TaskService.class)); TaskManager.updateSLARemainInDays(); } }
解决方案
在Mockito 4.x中,可通过Mockito.mockStatic()的重载方法结合MockedStaticSettings实现禁用类静态初始化的效果,替代原@SuppressStaticInitializationFor注解:
1. 确保依赖包含mockito-inline
Mockito 4.x的静态类Mock功能需要依赖mockito-inline模块(默认mockito-core不支持),Maven依赖配置如下:
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-inline</artifactId> <version>4.9.0</version> <scope>test</scope> </dependency>
2. 修改测试代码的静态Mock逻辑
创建MockedStatic实例时,通过withSettings().withoutStaticInitializer()设置禁用目标类的静态初始化:
@RunWith(MockitoJUnitRunner.class) public class TaskManagerTest { private MockedStatic<NonWorkingDayHelper> nonWorkingDayHelperMock; private MockedStatic<TaskService> taskServiceMock; @Before public void setUp(){ // 禁用NonWorkingDayHelper的静态初始化 nonWorkingDayHelperMock = Mockito.mockStatic(NonWorkingDayHelper.class, Mockito.withSettings().withoutStaticInitializer()); // 禁用TaskService的静态初始化 taskServiceMock = Mockito.mockStatic(TaskService.class, Mockito.withSettings().withoutStaticInitializer()); } @After public void tearDown(){ // 关闭静态Mock,避免影响其他测试 nonWorkingDayHelperMock.close(); taskServiceMock.close(); } @Test public void testUpdateSLARemainInDays() throws Exception { nonWorkingDayHelperMock.when(() -> NonWorkingDayHelper.isNonWorkingDay(any(Date.class))) .thenReturn(false); taskServiceMock.when(TaskService::getInstance) .thenReturn(Mockito.mock(TaskService.class)); TaskManager.updateSLARemainInDays(); } }
关键说明
withoutStaticInitializer()会完全阻止目标类的静态代码块执行及静态字段初始化,与原@SuppressStaticInitializationFor注解效果一致- 静态Mock实例需要在测试结束后调用
close()方法释放,避免对其他测试用例产生干扰
内容的提问来源于stack exchange,提问作者Pan Yichun
相关产品推荐
相关产品推荐

