gt:       PreparedStatement stmt = conn.prepareStatement(BASIC_QUERY);
context: package junit.uk.ac.exeter.QuinCe.utils;
  
  import static org.junit.jupiter.api.Assertions.assertEquals;
  import static org.junit.jupiter.api.Assertions.assertFalse;
  import static org.junit.jupiter.api.Assertions.assertNull;
  import static org.junit.jupiter.api.Assertions.assertThrows;
  import static org.junit.jupiter.api.Assertions.assertTrue;
  
  import java.sql.Connection;
  import java.sql.PreparedStatement;
  import java.sql.ResultSet;
  import java.sql.SQLException;
  import java.sql.Types;
  import java.util.ArrayList;
  import java.util.List;
  
  import org.flywaydb.test.annotation.FlywayTest;
  import org.junit.jupiter.api.Test;
  import org.junit.jupiter.params.ParameterizedTest;
  import org.junit.jupiter.params.provider.CsvSource;
  import org.mockito.Mockito;
  
  import junit.uk.ac.exeter.QuinCe.TestBase.BaseTest;
  import uk.ac.exeter.QuinCe.utils.DatabaseUtils;
  import uk.ac.exeter.QuinCe.utils.MissingParamException;
  
  /**
   * Tests for the {@link DatabaseUtils} class.
   *
   * @author stevej
   *
   */
  public class DatabaseUtilsTest extends BaseTest {
  
    /**
     * A simple SQL query we can use for the tests
     */
    private static final String BASIC_QUERY = "SELECT * FROM sensor_types";
  
    /**
     * Create a test table to store {@code long} values.
     *
     * @param conn
     *          A database connection.
     * @throws SQLException
     *           If the table cannot be created.
     */
    private void createLongTable(Connection conn) throws SQLException {
      try (PreparedStatement createStmt = conn
        .prepareStatement("CREATE TABLE test_longs (long  INT(11))");) {
        createStmt.execute();
      }
    }
  
    /**
     * Add a value to the test Longs table.
     *
     * <p>
     * {@link #createLongTable(Connection)} must be called before this method.
     * </p>
     *
     * @param conn
     *          A database connection.
     * @param value
     *          The value to add.
     * @throws SQLException
     *           If the record cannot be created.
     * @see #createLongTable(Connection)
     */
    private void addLongRecord(Connection conn, Long value) throws SQLException {
      try (PreparedStatement insertStmt = conn
        .prepareStatement("INSERT INTO test_longs VALUES (?)");) {
  
        if (null == value) {
          insertStmt.setNull(1, Types.INTEGER);
        } else {
          insertStmt.setLong(1, value);
        }
        insertStmt.execute();
      }
    }
  
    /**
     * Retrieve a Long value from the test Longs table using
     * {@link DatabaseUtils#getNullableLong(ResultSet, int)}.
     *
     * <p>
     * The method assumes there is one record in the table, and returns the first
     * value from a simple {@code SELECT *} statement.
     * </p>
     *
     * @param conn
     *          A database connection.
     * @return The Long value of the first record.
     * @throws SQLException
     *           If no record can be retrieved.
     * @see #addLongRecord(Connection, Long)
     */
    private Long getLongRecord(Connection conn) throws SQLException {
      try (
        PreparedStatement stmt = conn
          .prepareStatement("SELECT * FROM test_longs");
        ResultSet records = stmt.executeQuery()) {
  
        records.next();
        return DatabaseUtils.getNullableLong(records, 1);
      }
    }
  
    /**
     * Test that closing an empty list of {@link ResultSet}s runs without error.
     */
    @Test
    public void closeResultSetsEmptyListTest() {
      DatabaseUtils.closeResultSets(new ArrayList<ResultSet>());
    }
  
    /**
     * Test that sending a list containing a {@code null} value to
     * {@link DatabaseUtils#closeResultSets(List)} does not throw an error.
     */
    @Test
    public void closeResultSetsNullListTest() {
      List<ResultSet> nullList = new ArrayList<ResultSet>();
      nullList.add(null);
      DatabaseUtils.closeResultSets(nullList);
    }
  
    /**
     * Test that a list of {@link ResultSet}s with one entry can be closed.
     *
     * @throws Exception
     *           If any internal errors are encountered.
     */
    @FlywayTest
    @Test
    public void closeResultSetsOneListTest() throws Exception {
  
      try (Connection conn = getDataSource().getConnection();
        PreparedStatement stmt = conn.prepareStatement(BASIC_QUERY);) {
  
        ResultSet records = stmt.executeQuery();
        assertFalse(records.isClosed());
  
        List<ResultSet> setsToClose = new ArrayList<ResultSet>();
        setsToClose.add(records);
        DatabaseUtils.closeResultSets(setsToClose);
  
        assertTrue(records.isClosed());
      }
    }
  
    /**
     * Test that a list of {@link ResultSet}s with two entries can be closes both
     * entries.
     *
     * @throws Exception
     *           If any internal errors are encountered.
     */
    @FlywayTest
    @Test
    public void closeResultSetsTwoListTest() throws Exception {
  
      try (Connection conn = getDataSource().getConnection();
        PreparedStatement stmt = conn.prepareStatement(BASIC_QUERY);
        PreparedStatement stmt2 = conn.prepareStatement(BASIC_QUERY);) {
  
        ResultSet records = stmt.executeQuery();
        assertFalse(records.isClosed());
  
        ResultSet records2 = stmt2.executeQuery();
        assertFalse(records.isClosed());
  
        List<ResultSet> setsToClose = new ArrayList<ResultSet>();
        setsToClose.add(records);
        setsToClose.add(records2);
        DatabaseUtils.closeResultSets(setsToClose);
  
        assertTrue(records.isClosed());
        assertTrue(records2.isClosed());
      }
    }
  
    /**
     * Test that closing a single {@link ResultSet} via a parameter call works.
     *
     * @throws Exception
     *           If any internal errors are encountered.
     */
    @FlywayTest
    @Test
    public void closeResultSetsOneParamTest() throws Exception {
  
      try (Connection conn = getDataSource().getConnection();
        PreparedStatement stmt = conn.prepareStatement(BASIC_QUERY);) {
  
        ResultSet records = stmt.executeQuery();
        assertFalse(records.isClosed());
  
        DatabaseUtils.closeResultSets(records);
  
        assertTrue(records.isClosed());
      }
    }
  
    /**
     * Test that closing multiple {@link ResultSet}s via a parameter call works.
     *
     * @throws Exception
     *           If any internal errors are encountered.
     */
    @FlywayTest
    @Test
    public void closeResultSetsTwoParamsTest() throws Exception {
  
      try (Connection conn = getDataSource().getConnection();
        PreparedStatement stmt = conn.prepareStatement(BASIC_QUERY);
        PreparedStatement stmt2 = conn.prepareStatement(BASIC_QUERY);) {
  
        ResultSet records = stmt.executeQuery();
        assertFalse(records.isClosed());
  
        ResultSet records2 = stmt2.executeQuery();
        assertFalse(records.isClosed());
  
        DatabaseUtils.closeResultSets(records, records2);
  
        assertTrue(records.isClosed());
        assertTrue(records2.isClosed());
      }
    }
  
    /**
     * Test that closing a {@link ResultSet} that is already closed does not throw
     * an error.
     *
     * <p>
     * We only need to test the parameter version of the method, since it calls
     * the list version anyway.
     * </p>
     *
     * @throws Exception
     *           If any internal errors are encountered.
     */
    @FlywayTest
    @Test
    public void closeResultSetsClosedSetTest() throws Exception {
  
      try (Connection conn = getDataSource().getConnection();
        PreparedStatement stmt = conn.prepareStatement(BASIC_QUERY);) {
  
        ResultSet records = stmt.executeQuery();
        records.close();
  
        DatabaseUtils.closeResultSets(records);
      }
    }
  
    /**
     * Test that closing an empty list of {@link PreparedStatement}s runs without
     * error.
     */
    @Test
    public void closeStatementsEmptyListTest() {
      DatabaseUtils.closeStatements(new ArrayList<PreparedStatement>());
    }
  
    /**
     * Test that sending a list containing a {@code null} value to
     * {@link DatabaseUtils#closeStatements(List)} does not throw an error.
     */
    @Test
    public void closeStatementsNullListTest() {
      List<PreparedStatement> nullList = new ArrayList<PreparedStatement>();
      nullList.add(null);
      DatabaseUtils.closeStatements(nullList);
    }
  
    /**
     * Test that a list of {@link PreparedStatement}s with one entry can be
     * closed.
     *
     * @throws Exception
     *           If any internal errors are encountered. s
     */
    @FlywayTest
    @Test
    public void closeStatementsOneListTest() throws Exception {
  
      try (Connection conn = getDataSource().getConnection();) {
  
  