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

Quarkus 3中使用JMock Mock MapStruct Mapper时出现类转换异常

@QuarkusTest中Mock MapStruct Mapper的类型转换异常解决方案

问题重现

在@QuarkusTest环境下尝试用jMock Mock MapStruct Mapper,代码如下:

@RegisterExtension
JUnit5Mockery mockery = new JUnit5Mockery() {
    {
        setImposteriser(ByteBuddyClassImposteriser.INSTANCE);
        setThreadingPolicy(new Synchroniser());
    }
};

MyMapper mockMyMapper = mockery.mock(MyMapper.class);
QuarkusMock.installMockForType(mockMyMapper, MyMapper.class);

运行后触发类型转换异常:

java.lang.ClassCastException:

class com.example.MyMapper$jMock$yRbf640e
   cannot be cast to class com.example.MyMapperImpl

(com.example.MyMapper$jMock$yRbf640e is in unnamed module of loader 
   org.jmock.internal.SearchingClassLoader @510bd87a;
   com.example.MyMapperImpl
   is in unnamed module of loader
   io.quarkus.bootstrap.classloading.QuarkusClassLoader @1dbd580)

问题根源

  1. MapStruct会自动生成Mapper接口的实现类MyMapperImpl,Quarkus默认注入的是该实现类实例,而非接口实例。
  2. jMock生成的代理对象基于MyMapper接口创建,但Quarkus尝试将其强制转换为MyMapperImpl类型。
  3. 代理类和实现类由不同类加载器加载,JVM判定为不同类型,最终抛出转换异常。

解决方法

方法一:改用Quarkus原生支持的Mockito

Quarkus对Mockito有内置集成,直接Mock实现类即可避免类加载器问题:

@QuarkusTest
@MockBean(MyMapperImpl.class)
MyMapper mockMyMapper;

@Test
void testBusinessLogic() {
    // 配置Mock行为
    when(mockMyMapper.convert(any(Source.class))).thenReturn(new Target());
    // 执行测试逻辑并验证
}

方法二:确保依赖注入接口而非实现类

检查业务代码中的注入逻辑,确保注入的是MyMapper接口而非MyMapperImpl:

@Inject
MyMapper myMapper; // 正确:注入接口类型
// @Inject MyMapperImpl myMapper; // 错误:直接注入实现类会导致Mock匹配失败

这样Quarkus注入时会识别接口类型的Mock对象,不会触发强转操作。

方法三:调整jMock的类加载器配置

如果必须使用jMock,需让其生成的代理类使用Quarkus的类加载器:

@RegisterExtension
JUnit5Mockery mockery = new JUnit5Mockery() {
    {
        setImposteriser(ByteBuddyClassImposteriser.INSTANCE);
        setThreadingPolicy(new Synchroniser());
        // 指定类加载器为当前线程的上下文类加载器(即Quarkus类加载器)
        setClassLoader(Thread.currentThread().getContextClassLoader());
    }
};

同时配合接口注入的方式,即可解决类型转换问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 10:50:29