### Question:
JdbcDaoTemplate { public Object execute(String sql, boolean returnKey, ParameterMapper parameterMapper, PreparedCallback preparedCallback) { try { Connection conn = datasource.getConnection(); try { PreparedStatement statement; if(returnKey) { statement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); } else { statement = conn.prepareStatement(sql); } try { if (parameterMapper != null) { parameterMapper.mapParameters(statement); } return preparedCallback.process(statement); } finally { statement.close(); } } finally { conn.close(); } } catch (SQLException ex) { throw new SQLDaoException(ex); } } JdbcDaoTemplate(DataSource datasource); List<T> query(String sql, ColumnMapper<T> columnMapper); List<T> query(String sql, ParameterMapper parameterMapper, final ColumnMapper<T> columnMapper); void update(String sql, ParameterMapper parameterMapper); List<Number> insert(String sql, ParameterMapper parameterMapper); List<Number> update(String sql, final boolean returnKey, ParameterMapper parameterMapper); Object execute(String sql, boolean returnKey, ParameterMapper parameterMapper, PreparedCallback preparedCallback); DataSource getDatasource();  }### Answer:
@Test public void testExecute() throws SQLException { final PreparedStatement mockStatement = mock(PreparedStatement.class); when(mockConnection.prepareStatement("SQL")).thenReturn(mockStatement); final StringBuffer parameter = new StringBuffer(); Object result = template.execute("SQL", false, new ParameterMapper() { @Override public void mapParameters(PreparedStatement statement) throws SQLException { assertSame(mockStatement, statement); parameter.append("parameter"); } }, new PreparedCallback() { @Override public Object process(PreparedStatement statement) throws SQLException { assertSame(mockStatement, statement); return("result"); } }); assertEquals("result", result); assertEquals("parameter", parameter.toString()); verify(mockStatement).close(); verify(mockConnection).close(); }
@Test public void testExecuteWithoutParams() throws SQLException { final PreparedStatement mockStatement = mock(PreparedStatement.class); when(mockConnection.prepareStatement("SQL")).thenReturn(mockStatement); Object result = template.execute("SQL", false, null, new PreparedCallback() { @Override public Object process(PreparedStatement statement) throws SQLException { assertSame(mockStatement, statement); return("result"); } }); assertEquals("result", result); verify(mockStatement).close(); verify(mockConnection).close(); }
@Test public void testExecuteWithReturnKeys() throws SQLException { final PreparedStatement mockStatement = mock(PreparedStatement.class); when(mockConnection.prepareStatement("SQL", Statement.RETURN_GENERATED_KEYS)) .thenReturn(mockStatement); Object result = template.execute("SQL", true, null, new PreparedCallback() { @Override public Object process(PreparedStatement statement) throws SQLException { assertSame(mockStatement, statement); return("result"); } }); assertEquals("result", result); verify(mockStatement).close(); verify(mockConnection).close(); }
@Test public void testExecuteThrowException() throws SQLException { final PreparedStatement mockStatement = mock(PreparedStatement.class); when(mockConnection.prepareStatement("SQL")).thenReturn(mockStatement); try { template.execute("SQL", false, null, new PreparedCallback() { @Override public Object process(PreparedStatement statement) throws SQLException { assertSame(mockStatement, statement); throw new SQLException(); } }); fail("SQLDaoException expected"); } catch(SQLDaoException ex) { verify(mockStatement).close(); verify(mockConnection).close(); } }