为什么当我使用带有某些参数的 Mockito 抛出 SqlException 时无法识别?

问题描述

我有 Dao 方法,根据 sql 错误代码抛出几个异常。所有这些都会转到服务层。

fdatasync()

在 Service 层,我捕获它们并根据 Dao 层中抛出的异常抛出其他异常。

服务层

public boolean insertUser(Connection connection,User user) throws MysqLEXContainer.MysqLdbnotUniqueException,MysqLEXContainer.MysqLDBLargeDataException,MysqLEXContainer.MysqLDBExecutionException,sqlException {
        int rowNum = 0;
        ResultSet keys = null;
        Connection con;
        PreparedStatement statement = null;
        try {
            String query = QueriesUtil.getQuery("insertUser");
            con = connection;
            statement = con.prepareStatement(query,Statement.RETURN_GENERATED_KEYS);
            statement.setString(1,user.getLogin());
            statement.setString(2,PasswordUtil.generateStrongPasswordHash(user.getpassword()));
            statement.setString(3,user.getUserType());
            statement.setString(4,user.getUserEmail());
            rowNum = statement.executeUpdate();
            keys = statement.getGeneratedKeys();
            if (keys.next()) {
                user.setUserId(keys.getInt(1));
            }
        } catch (sqlException e) {
            LOGGER.error(e);
            if (e.getErrorCode() == 1062) {
                throw new MysqLEXContainer.MysqLdbnotUniqueException(String.format("Your login : %s or Email %s already exists",user.getLogin(),user.getUserEmail()),e.getCause());
            } else if (e.getErrorCode() == 1406) {
                throw new MysqLEXContainer.MysqLDBLargeDataException("Data Is too long",e);
            }
            throw new MysqLEXContainer.MysqLDBExecutionException("Bad execution",e);
        } finally {
            ConnectionUtil.oneMethodToCloseThemAll(keys,statement,null);
        }
        return rowNum > 0;
    }

在测试类中,我有这个检查异常的方法

public boolean insertUser(User user) throws ApplicationEXContainer.ApplicationCanNotChangeException,ApplicationEXContainer.ApplicationCanChangeException {
        boolean result=false;
        try(Connection connection = MysqLDAOFactory.getConnection();
            AutoRollback autoRollback = new AutoRollback(connection)){
            result =  userDao.insertUser(connection,user);
            autoRollback.commit();
        } catch (sqlException | NamingException | MysqLEXContainer.MysqLDBExecutionException throwables) {
            throw new ApplicationEXContainer.ApplicationCanNotChangeException(throwables);
        } catch (MysqLEXContainer.MysqLDBLargeDataException | MysqLEXContainer.MysqLdbnotUniqueException MysqLDBExceptionCanChange) {
            throw new ApplicationEXContainer.ApplicationCanChangeException(MysqLDBExceptionCanChange.getMessage(),MysqLDBExceptionCanChange);
        }
        return result;
    }

在 webapp 中一切正常,但是当我使用 Mockito 时,我得到了这个 StackTrace

@Test
    void insertUserNotUniqueException() throws sqlException,MysqLEXContainer.MysqLdbnotUniqueException,ApplicationEXContainer.ApplicationCanNotChangeException,ApplicationEXContainer.ApplicationCanChangeException {
        User user = new User();
        when(userDao.insertUser(any(Connection.class),any(User.class))).thenThrow(new sqlException("Login or Email is already in database","23000",1062));
        Throwable thrown = assertThrows(ApplicationEXContainer.ApplicationCanChangeException.class,()->taxiServiceUser.insertUser(user));
        assertEquals("Login or Email is already in database",thrown.getMessage());
    }

所以User Dao插入方法抛出错误异常。 为什么会这样?

解决方法

我认为您只是犯了一个错误:在下面复制的代码中突出显示了兴趣点

public boolean insertUser(User user) throws ApplicationEXContainer.ApplicationCanNotChangeException,ApplicationEXContainer.ApplicationCanChangeException {
        boolean result=false;
        try(Connection connection = MySQLDAOFactory.getConnection();
            AutoRollback autoRollback = new AutoRollback(connection)){
            result =  userDao.insertUser(connection,user); // here it throws an SQLException
            autoRollback.commit();
        } catch (SQLException | NamingException | MySQLEXContainer.MySQLDBExecutionException throwables) {
// here it catches and throws exactly the exception the test says was thrown
            throw new ApplicationEXContainer.ApplicationCanNotChangeException(throwables); 
        } catch (MySQLEXContainer.MySQLDBLargeDataException | MySQLEXContainer.MySQLDBNotUniqueException mySQLDBExceptionCanChange) {
            throw new ApplicationEXContainer.ApplicationCanChangeException(mySQLDBExceptionCanChange.getMessage(),mySQLDBExceptionCanChange);
        }
        return result;
  }

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...