当前位置: 首页 > 知识库问答 >
问题:

为什么当我使用带有一些参数的Mockito抛出SqlException时,它不被识别?

毛景曜
2023-03-14

我有一个根据Sql错误代码抛出几个异常的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;
    }

在服务层,我捕获它们并根据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);
            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;
    }

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

@Test
    void insertUserNotUniqueException() throws SQLException, MySQLEXContainer.MySQLDBExecutionException, MySQLEXContainer.MySQLDBLargeDataException, 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());
    }

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

org.opentest4j.AssertionFailedError: Unexpected exception type thrown ==> expected: <com.example.FinalProjectPM.db.exception.ApplicationEXContainer.ApplicationCanChangeException> but was: <com.example.FinalProjectPM.db.exception.ApplicationEXContainer.ApplicationCanNotChangeException>

    at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:65)
    at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:37)
    at org.junit.jupiter.api.Assertions.assertThrows(Assertions.java:3007)
    at com.example.FinalProjectPM.db.services.TaxiServiceUserTest.insertUserNotUniqueException(TaxiServiceUserTest.java:53)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.util.ArrayList.forEach(ArrayList.java:1259)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.util.ArrayList.forEach(ArrayList.java:1259)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: com.example.FinalProjectPM.db.exception.ApplicationEXContainer$ApplicationCanNotChangeException: java.sql.SQLException: Login or Email is already in database
    at com.example.FinalProjectPM.db.services.TaxiServiceUser.insertUser(TaxiServiceUser.java:28)
    at com.example.FinalProjectPM.db.services.TaxiServiceUserTest.lambda$insertUserNotUniqueException$0(TaxiServiceUserTest.java:53)
    at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:55)
    ... 68 more
Caused by: java.sql.SQLException: Login or Email is already in database
    at com.example.FinalProjectPM.db.services.TaxiServiceUser.insertUser(TaxiServiceUser.java:25)
    ... 70 more

所以用户 Dao 插入方法抛出错误的异常。为什么会发生这种情况?

共有1个答案

宰父浩漫
2023-03-14

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

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;
  }
 类似资料:
  • 在index.hpp中,我创建了一个具有多个数据成员的类,如、等。我在类外部定义了一个构造函数。在program.cpp中,我创建了一个名为SAM的对象。当我试图编译它时,它显示错误。什么原因? Program.cpp index.hpp 错误信息

  • 我创建了一个从HashMap中删除学生的方法。当id为NULL时,它会抛出一个异常。有人知道它为什么不起作用吗? 公共类应用程序{public static void main(String[]args){ }

  • 当使用Mockito截尾时,我们通常为一个方法指定一个具体的参数。之后,我们可以用相同的参数调用Stubed方法。例如,在下面的代码中,get()用参数0进行了stubed。所以,当调用get()时,get()的参数也是0。因此,get()将返回一个整数,即3。 如果调用语句被修改为: 即参数更改为1,然后Mockito抛出“NullPointerException”,而不是“AssertionE

  • 以下是异常日志: 下面是android.app.ContextImpl.GetSharedReferences异常抛出的代码 让我们假设日志信息是正确的,它应该几乎是正确的。 我的第一个问题是:在文件的第358行抛出强制转换异常ContextImpl.java什么意思?那里只有一个右括号。 我猜第358行下面的语句是异常的根本原因 因为sp被声明为SharedReferencesImpl,并且当g

  • 我有一个Spring/JPA配置,其中Hibernate作为持久性提供者。但是,我不明白为什么在没有打开事务的情况下对以下DAO代码调用save()时没有抛出TransactionRequiredException(DAO/服务中没有@Transactional): 正如预期的那样,实体没有保存,但为什么没有引发异常?持久化的javadoc表示,持久化()应该抛出一个“Transaction必需的

  • 问题内容: 当我运行以下代码片段时 我收到以下消息: 并有4个条目(与打印相对应的3的a为0(实际错误为18) 但是,如果我替换为,则会得到预期的结果: 消息是,我在…中只有一个条目 有什么办法可以避免??的奇怪行为? 问题答案: 不,您无法避免这种行为。它是TdsParser.ThrowExceptionAndWarning()编写方式的结果 特别是这条线 我的猜测是,无论出于何种原因,对于Ex