代码之家  ›  专栏  ›  技术社区  ›  Sither Tsering

Mockito:mockStatic.when().then Throw()行为

  •  0
  • Sither Tsering  · 技术社区  · 1 年前

    我正在为一个抛出各种异常的方法编写测试。这个测试用例是抛出SQLException,我注意到了这些行为。

    @Test
    public void testGetPreparedStatement_throwsSQLException() throws Exception {
        try (MockedStatic<DriverManager> mockedDriverManager = mockStatic(DriverManager.class)) {
            // Throws org.mockito.exceptions.misusing.UnfinishedStubbingException
            mockedDriverManager.when(() -> DriverManager.getConnection(anyString(), anyString(), anyString()))
                    .thenThrow(new SQLException("some message"));
    
            assertThrows(SQLException.class, () -> ((RequestDBServiceJDBC) RequestDBServiceJDBC.getInstance())
                    .getPreparedStatement(new RequestCriteria()));
        }
    }
    
    // But somehow this works:
    SQLException sqlException = new SQLException("some message");
    mockedDriverManager.when(() -> DriverManager.getConnection(anyString(), anyString(), anyString()))
        .thenThrow(sqlException);
    

    错误:

    org.mockito.exceptions.misusing.UnfinishedStubbingException: 
    Unfinished stubbing detected here:
    -> at at com.devcenter.myproject.request.service.jdbc.RequestDBServiceJDBCTest.testGetPreparedStatement_throwsSQLException(RequestDBServiceJDBCTest.java:206)
    
    E.g. thenReturn() may be missing.
    Examples of correct stubbing:
        when(mock.isOk()).thenReturn(true);
        when(mock.isOk()).thenThrow(exception);
        doThrow(exception).when(mock).someVoidMethod();
    Hints:
     1. missing thenReturn()
     2. you are trying to stub a final method, which is not supported
     3. you are stubbing the behaviour of another mock inside before 'thenReturn' instruction is completed
    
        at java.sql/java.sql.DriverManager.getLogWriter(DriverManager.java:129)
        at java.sql/java.sql.SQLException.<init>(SQLException.java:125)
        at com.devcenter.myproject.request.service.jdbc.RequestDBServiceJDBCTest.testGetPreparedStatement_throwsSQLException(RequestDBServiceJDBCTest.java:207)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    

    对此有什么解释吗?

    1 回复  |  直到 1 年前
        1
  •  2
  •   talex    1 年前

    SQLException 构造函数调用 DriverManager.getLogWriter .

    在完成之前,不允许调用模拟类的方法 when().thenXXX() 序列。

    您必须先构造异常 when 打电话。

    或者,您可以使用 .then(x -> { throw new SQLException("some message");}) 而不是 thenThrow .