@Test
public void shouldCreateSecondConnectionAfterFirstThrowsExceptionInsideExecuteQuery() throws Exception {

    PreparedStatement mockReplacedPreparedStatement = mock(PreparedStatement.class);
    when(mockConnection.prepareStatement(anyString())).thenReturn(mockPreparedStatement);
    when(mockReplacedConnection.prepareStatement(anyString())).thenReturn(mockReplacedPreparedStatement);
    final JDBCBase.StatementWithReturnBlock<?> mockStatementWithReturnBlock = mock(JDBCBase.StatementWithReturnBlock.class);
    final List<PreparedStatement> statementsUsed = Lists.newArrayList();
    // store the connections used
    doAnswer(new Answer() {
        @Override
        public Object answer(InvocationOnMock invocation) throws Throwable {
            statementsUsed.add((PreparedStatement) invocation.getArguments()[0]);
            // the first call will throw
            if (statementsUsed.size() == 1) {
                throw new IllegalArgumentException("first invocation");
            }
            return null;
        }
    }).when(mockStatementWithReturnBlock).use(any(PreparedStatement.class));
    initializeJDBCTestSubclass();
    // check that the first call throws
    assertThatExceptionIsThrown(new Callable<Void>() {
        @Override
        public Void call() throws Exception {
            jdbcTestSubclass.executeQuery("SOME SQL", mockStatementWithReturnBlock);
            return null;
        }
    }, IllegalArgumentException.class);
    // and that we clean up properly
    InOrder inOrder = inOrder(mockPreparedStatement, mockConnection);
    inOrder.verify(mockPreparedStatement).close();
    inOrder.verify(mockConnection).rollback();
    inOrder.verify(mockConnection).close();
    // call again, and verify that the connection was replaced
    jdbcTestSubclass.executeQuery("ANOTHER SQL QUERY", mockStatementWithReturnBlock);
    // check that we were handed two different prepared statements (which could only be created by two different mock connections)
    assertThat(statementsUsed, hasSize(2));
    assertThat(statementsUsed, contains(mockPreparedStatement, mockReplacedPreparedStatement));
}