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

Quarkus集成测试@InjectMock EntityManager报WrongTypeOfReturnValue异常

解决Quarkus集成测试中@InjectMock EntityManager的WrongTypeOfReturnValue异常

问题场景

在Quarkus集成测试中,使用@InjectMock注入EntityManager后,尝试mock其createNamedQuery(String, Class)方法返回TypedQuery时,触发WrongTypeOfReturnValue异常,提示该方法应返回Query而非TypedQuery。该测试在普通单元测试中正常运行,仅在Quarkus集成测试环境下报错。

解决方案

将Mockito的when(...).thenReturn()语法替换为doReturn(...).when()语法,避免触发真实的createNamedQuery方法调用。

修改后的测试代码片段:

@Test
public void testCreateActiveSubscription() {
    // -- prepare
    TypedQuery<TransactionEventEntity> trxQuery = mock(TypedQuery.class);
    // 使用doReturn替代when...thenReturn
    doReturn(trxQuery).when(entityManager).createNamedQuery(eq("selectTransactionsFrom"), eq(TransactionEventEntity.class));
    TransactionEventEntity transactionEventEntity = new TransactionEventEntity();
    // 后续测试逻辑...
}

原因说明

在Quarkus集成测试环境中,@InjectMock注入的EntityManager并非纯Mockito mock实例,而是被CDI代理包装后的对象。当使用when(entityManager.createNamedQuery(...)).thenReturn()语法时,会先执行一次真实的createNamedQuery方法调用,而CDI代理返回的实例类型为Query(而非预期的TypedQuery),导致Mockito检测到返回值类型不匹配,抛出异常。

doReturn(...).when()语法不会触发真实方法的执行,直接指定mock方法的返回值,绕过了CDI代理的真实调用逻辑,从而避免类型不匹配的问题。

额外提示

如果需要控制@Scheduled注解的scan方法触发时机,可以在测试类中添加@DisableScheduled注解(Quarkus内置)禁用定时任务,手动调用方法测试:

@QuarkusTest
@QuarkusTestResource(WireMockLCM.class)
@DisableScheduled // 禁用所有定时任务
public class BroEventGeneratorTest {
    // ...

    @Test
    public void testCreateActiveSubscription() {
        // ... mock逻辑
        // 手动调用scan方法
        yourBeanInstance.scan();
        // 断言逻辑
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:43:21