You need to enable JavaScript to run this app. 使用Mockito带参数抛出SQLException时无法被正确识别是什么原因?
优惠活动
大模型
产品
解决方案
定价
更多

使用Mockito带参数抛出SQLException时无法被正确识别是什么原因?

问题根本原因

测试代码中直接Mock Dao层方法抛出原始SQLException,跳过了Dao层本身的异常转换逻辑,是该问题的核心诱因。

两种运行流程差异

  • 线上正常运行流程:Dao层insertUser方法内部会捕获SQLException,当错误码为1062时会转换为MySQLEXContainer.MySQLDBNotUniqueException再向外抛出,Service层捕获到该自定义异常后会匹配第二个catch块,抛出符合预期的ApplicationCanChangeException。
  • 测试Mock流程:通过Mockito指定userDao.insertUser直接抛出原始SQLException,没有执行Dao层内部的异常转换代码,Service层的第一个catch块直接匹配到SQLException,因此抛出了ApplicationCanNotChangeException,和测试预期不符。

修复方案

修改测试代码中Mock抛出的异常类型,改为Dao层转换后的自定义异常即可:

@Test
void insertUserNotUniqueException() throws SQLException, MySQLEXContainer.MySQLDBExecutionException, MySQLEXContainer.MySQLDBLargeDataException, MySQLEXContainer.MySQLDBNotUniqueException, ApplicationEXContainer.ApplicationCanNotChangeException, ApplicationEXContainer.ApplicationCanChangeException {
    User user = new User();
    user.setLogin("testLogin");
    user.setUserEmail("test@example.com");
    // 改为抛出DAO转换后的自定义异常
    when(userDao.insertUser(any(Connection.class),any(User.class))).thenThrow(new MySQLEXContainer.MySQLDBNotUniqueException(String.format("Your login : %s or Email %s already exists", user.getLogin(), user.getUserEmail()), new SQLException()));
    Throwable thrown = assertThrows(ApplicationEXContainer.ApplicationCanChangeException.class,()->taxiServiceUser.insertUser(user));
    assertEquals("Your login : testLogin or Email test@example.com already exists",thrown.getMessage());
}

如果需要验证Dao层的异常转换逻辑,建议单独编写Dao层单元测试,不需要耦合在Service层的测试逻辑中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 03:15:08