You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 8升级至21后Arquillian集成测试中Mockito.mock失效问题

解决JUnit4+远程Wildfly+Arquillian环境下Mockito初始化异常问题

问题背景

将Java版本从8升级到21后,使用远程Wildfly配合Arquillian做JUnit4集成测试时,测试类中调用Mockito.mock()方法抛出初始化异常:

java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
at deployment.testarchive.war//org.mockito.internal.configuration.plugins.PluginLoader$1.invoke(PluginLoader.java:85)
...(省略部分栈追踪内容)

尝试过相关解决方案但因JUnit4+远程Wildfly环境不生效,移除测试类的@RunWith(Arquillian.class)后Mockito可正常运行,但集成测试无法执行。当前Arquillian的WAR部署代码如下:

@ArquillianSuiteDeployment
public class Deployments {
    @Deployment
    public static WebArchive deploy(){
        return ShrinkWrap.create(WebArchive.class,"testarchive.war")
                .addPackages(true,"at.felder")
                ...(省略部分配置代码)
               .addAsResource("org/apache/commons/vfs2/impl/providers.xml");
    }
}

解决方案

1. 对齐依赖版本兼容性

Java 21需要搭配Mockito 5.x及以上版本,同时确保Arquillian核心、远程Wildfly容器适配器的版本适配Java 21和JUnit4:

  • Mockito选择5.6.0或更高版本
  • Arquillian核心使用1.7.0.Final及以上版本
  • Wildfly容器适配器选用对应Wildfly版本的适配包(如Wildfly 29+适配Java 21)

2. 从部署包中移除Mockito相关依赖

远程Wildfly环境中,Mockito是测试端工具,不需要被打包进部署到服务器的WAR中,否则会引发服务器类加载器与测试类加载器的冲突。修改部署代码,排除Mockito及其依赖:

@ArquillianSuiteDeployment
public class Deployments {
    @Deployment
    public static WebArchive deploy(){
        return ShrinkWrap.create(WebArchive.class,"testarchive.war")
                .addPackages(true, "at.felder")
                // 排除Mockito及依赖类,避免服务器端加载
                .exclude("org.mockito.**")
                .exclude("net.bytebuddy.**")
                .exclude("org.objenesis.**")
                ...(省略部分配置代码)
               .addAsResource("org/apache/commons/vfs2/impl/providers.xml");
    }
}

同时在Maven/Gradle配置中,确保Mockito依赖的scope为test,不会被打包进WAR。

3. 使用Arquillian Mockito扩展管理Mock对象

引入Arquillian的Mockito扩展,它能在JUnit4+Arquillian环境中正确处理Mock的初始化,避免插件加载异常:

  • 添加Maven依赖:
<dependency>
    <groupId>org.jboss.arquillian.extension</groupId>
    <artifactId>arquillian-mockito</artifactId>
    <version>1.1.0.Final</version>
    <scope>test</scope>
</dependency>
  • 在测试类中用@Mock注解创建Mock,替代直接调用Mockito.mock():
@RunWith(Arquillian.class)
public class YourIntegrationTest {
    @Mock
    private YourDependency mockDependency;

    // 被测服务由Arquillian注入
    @Inject
    private YourService serviceUnderTest;

    @Before
    public void setup() {
        // 初始化Mock
        MockitoAnnotations.initMocks(this);
        // 配置Mock行为
        when(mockDependency.someMethod()).thenReturn("expectedResult");
    }

    @Test
    public void testServiceLogic() {
        serviceUnderTest.execute();
        // 验证Mock调用
        verify(mockDependency).someMethod();
    }
}

4. 排查类加载器配置

远程Wildfly环境下,测试客户端与服务器的类加载器相互隔离。确保测试运行时,Mockito的JAR只存在于测试类路径中,不会被部署到服务器。可以通过解压WAR包检查是否意外包含了Mockito相关文件。

内容的提问来源于stack exchange,提问作者MJCM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 23:02:01