### Question:
PoolAwareConnection implements Connection { @Override public PreparedStatement prepareStatement(String sql) throws SQLException { try { return connection.prepareStatement(sql); } catch (SQLException sqlEx) { recover(sqlEx); return connection.prepareStatement(sql); } } PoolAwareConnection(UnmanagedPoolingDataSource parent, Connection connection, String validationQuery); @Override void clearWarnings(); @Override void close(); @Override void commit(); @Override Statement createStatement(); @Override Statement createStatement(int resultSetType, int resultSetConcurrency); @Override boolean getAutoCommit(); @Override String getCatalog(); @Override DatabaseMetaData getMetaData(); @Override int getTransactionIsolation(); @Override SQLWarning getWarnings(); @Override boolean isClosed(); @Override boolean isReadOnly(); @Override String nativeSQL(String sql); @Override CallableStatement prepareCall(String sql); @Override CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency); @Override PreparedStatement prepareStatement(String sql); @Override PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency); @Override void rollback(); @Override void setAutoCommit(boolean autoCommit); @Override void setCatalog(String catalog); @Override void setReadOnly(boolean readOnly); @Override void setTransactionIsolation(int level); @Override Map<String, Class<?>> getTypeMap(); @Override void setTypeMap(Map<String, Class<?>> map); @Override void setHoldability(int holdability); @Override int getHoldability(); @Override Savepoint setSavepoint(); @Override Savepoint setSavepoint(String name); @Override void rollback(Savepoint savepoint); @Override void releaseSavepoint(Savepoint savepoint); @Override Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability); @Override PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
			int resultSetHoldability); @Override CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
			int resultSetHoldability); @Override PreparedStatement prepareStatement(String sql, int autoGeneratedKeys); @Override PreparedStatement prepareStatement(String sql, int[] columnIndexes); @Override PreparedStatement prepareStatement(String sql, String[] columnNames); @Override Array createArrayOf(String typeName, Object[] elements); @Override Blob createBlob(); @Override Clob createClob(); @Override Struct createStruct(String typeName, Object[] attributes); @Override Properties getClientInfo(); @Override String getClientInfo(String name); @Override boolean isValid(int timeout); @Override boolean isWrapperFor(Class<?> iface); @SuppressWarnings("unchecked") @Override T unwrap(Class<T> iface); @Override NClob createNClob(); @Override SQLXML createSQLXML(); @Override void setClientInfo(Properties properties); @Override void setClientInfo(String name, String value); @Override void setSchema(String schema); @Override String getSchema(); @Override void abort(Executor executor); @Override void setNetworkTimeout(Executor executor, int milliseconds); @Override int getNetworkTimeout();  }### Answer:
@Test public void testPrepareStatement() throws SQLException { PreparedStatement firstTry = mock(PreparedStatement.class); PreparedStatement secondTry = mock(PreparedStatement.class); when(connectionMock.prepareStatement(anyString())).thenReturn(firstTry, secondTry); PoolAwareConnection paConnection = new PoolAwareConnection(parentMock, connectionMock, null); PreparedStatement st = paConnection.prepareStatement("SELECT 1"); assertSame(firstTry, st); }
@Test public void testPrepareStatement_Recover() throws SQLException { PreparedStatement secondTry = mock(PreparedStatement.class); when(connectionMock.prepareStatement(anyString())).thenThrow(new SQLException("E1")).thenReturn(secondTry); PoolAwareConnection paConnection = new PoolAwareConnection(parentMock, connectionMock, null); PreparedStatement st = paConnection.prepareStatement("SELECT 1"); assertSame(secondTry, st); }
@Test public void testPrepareStatement_Recover_Impossible() throws SQLException { SQLException original = new SQLException("E1"); when(connectionMock.prepareStatement(anyString())).thenThrow(original); PoolAwareConnection paConnection = new PoolAwareConnection(parentMock, connectionMock, null); try { paConnection.prepareStatement("SELECT 1"); } catch (SQLException e) { assertSame(original, e); } }