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

Mock Lambda表达式时遇ClassCastException及提取参数问题求助

问题解决:Hibernate doWork 类型转换异常及参数验证

异常情况

调用测试代码时出现类型转换异常:

java.lang.ClassCastException: com.paypal.compliance.data.process.eftns.dao.impl.EFTReportsDAO$$Lambda$9/170106909 cannot be cast to java.util.function.Consumer

对应的测试代码块:

when(session.doWork(any())).thenAnswer(invocation -> {
    Consumer<Connection> consumer = invocation.getArgument(0);
    consumer.accept(mockConnection);
    return null;
}); 

核心原因

Hibernate Session.doWork() 方法接受的参数是**Work接口**(而非Consumer<Connection>),你传入的Lambda表达式实际实现的是Work接口,强行转成Consumer必然抛出类型转换异常。

另外你调试时看到的arg$1(SQL语句)和arg$2(EFTReportsDO列表)并非doWork方法的参数,而是Lambda捕获的外部变量,无法通过invocation.getArgument()直接提取。

解决方案

1. 修复类型转换异常

将测试中的类型转换改为Work接口,调用其execute方法:

when(session.doWork(any())).thenAnswer(invocation -> {
    // 正确获取Work实例,而非Consumer
    Work work = invocation.getArgument(0);
    work.execute(mockConnection);
    return null;
});

2. 验证SQL语句与列表数据

若要验证SQL语句和批量更新的参数,可通过Mock对象的调用验证实现:

  • 验证SQL语句是否正确传入:
verify(connection).prepareStatement(eq("UPDATE EFT_XYZ SET COMMENTS=?, PP_BATCH_SOURCE=?, WHERE PP_BATCH_ID=? AND REPORT_ID=?"));
  • 验证批量参数是否正确设置(需给测试用的EFTReportsDO设置真实值):
// 验证第一个实体的参数设置
verify(preparedStatement).setString(1, eftReportsDO.getComments());
verify(preparedStatement).setString(2, eftReportsDO.getPpBatchSource());
verify(preparedStatement).setString(3, eftReportsDO.getId().getPpBatchId());
verify(preparedStatement).setString(4, eftReportsDO.getId().getReportId());
// 验证批量操作调用次数
verify(preparedStatement, times(1)).addBatch();
verify(preparedStatement, times(1)).executeBatch();

完整修正后的测试代码

@Test
public void testMergeAllEftReports() throws SQLException {
    // Arrange
    List<EFTReportsDO> instanceList = new ArrayList<>();
    EFTReportsDO eftReportsDO = new EFTReportsDO();
    // 给实体设置测试用真实值
    eftReportsDO.setComments("test comment");
    eftReportsDO.setPpBatchSource("test source");
    EFTReportsId id = new EFTReportsId();
    id.setPpBatchId("batch123");
    id.setReportId("report456");
    eftReportsDO.setId(id);
    instanceList.add(eftReportsDO);

    when(entityManager.unwrap(Session.class)).thenReturn(session);
    Connection mockConnection = mock(Connection.class);
    PreparedStatement preparedStatement = mock(PreparedStatement.class);
    when(mockConnection.prepareStatement(anyString())).thenReturn(preparedStatement);

    // 修复类型转换问题
    when(session.doWork(any())).thenAnswer(invocation -> {
        Work work = invocation.getArgument(0);
        work.execute(mockConnection);
        return null;
    });

    // Act
    eftReportsDAO.mergeAllEftReports(instanceList);

    // Assert
    // 验证SQL语句正确性
    verify(mockConnection).prepareStatement(eq("UPDATE EFT_XYZ SET COMMENTS=?, PP_BATCH_SOURCE=?, WHERE PP_BATCH_ID=? AND REPORT_ID=?"));
    // 验证参数设置
    verify(preparedStatement).setString(1, "test comment");
    verify(preparedStatement).setString(2, "test source");
    verify(preparedStatement).setString(3, "batch123");
    verify(preparedStatement).setString(4, "report456");
    // 验证批量操作
    verify(preparedStatement, times(1)).addBatch();
    verify(preparedStatement, times(1)).executeBatch();
    // 验证EntityManager的flush和close调用
    verify(entityManager, times(1)).flush();
    verify(entityManager, times(1)).close();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 16:08:21