Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Mockito: mockStatic.when().thenThrow() behavior

I’m writing a test for a method that throws various exception. This test case is to throw SQLException and I noticed these behavior.

@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);

Error:

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)

Is there any explanation for this?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

SQLException constructor calls DriverManager.getLogWriter.

It is not allowed to call methods of mocked class before you finished when().thenXXX() sequence.

You have to construct exception before when called.

Alternatively you can use .then(x -> { throw new SQLException("some message");}) instead of thenThrow.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading