Home » Java » Core Java » Java: Mocking a ResultSet using Mockito

About Fahd Shariff

Fahd Shariff
Fahd is a software engineer working in the financial services industry. He is passionate about technology and specializes in Java application development in distributed environments.

Java: Mocking a ResultSet using Mockito

This post shows how you can mock a java.sql.ResultSet using Mockito. It can be used to help unit test code which performs operations on ResultSets (such as a ResultSetExtractor) without relying on an external datasource.

You can create a MockResultSet by providing a list of column names and a 2D array of data. For example:

var rs = MockResultSet.create(
           new String[] { "name", "age" }, //columns
           new Object[][] { // data
             { "Alice", 20 },
             { "Bob", 35 },
             { "Charles", 50 }
           });

The code for MockResultSet is shown below (also available in my GitHub Repository). Note that I have only mocked a few methods such as next, getString and getObject but it is quite easy to mock the rest by following the same pattern.

public class MockResultSet {

  private final Map<String, Integer> columnIndices;
  private final Object[][] data;
  private int rowIndex;

  private MockResultSet(final String[] columnNames,
                        final Object[][] data) {
    // create a map of column name to column index
    this.columnIndices = IntStream.range(0, columnNames.length)
        .boxed()
        .collect(Collectors.toMap(
            k -> columnNames[k],
            Function.identity(),
            (a, b) ->
              { throw new RuntimeException("Duplicate column " + a); },
            LinkedHashMap::new
            ));
    this.data = data;
    this.rowIndex = -1;
  }

  private ResultSet buildMock() throws SQLException {
    final var rs = mock(ResultSet.class);

    // mock rs.next()
    doAnswer(invocation -> {
      rowIndex++;
      return rowIndex < data.length;
    }).when(rs).next();

    // mock rs.getString(columnName)
    doAnswer(invocation -> {
      final var columnName = invocation.getArgumentAt(0, String.class);
      final var columnIndex = columnIndices.get(columnName);
      return (String) data[rowIndex][columnIndex];
    }).when(rs).getString(anyString());

    // mock rs.getObject(columnIndex)
    doAnswer(invocation -> {
      final var index = invocation.getArgumentAt(0, Integer.class);
      return data[rowIndex][index - 1];
    }).when(rs).getObject(anyInt());

    final var rsmd = mock(ResultSetMetaData.class);

    // mock rsmd.getColumnCount()
    doReturn(columnIndices.size()).when(rsmd).getColumnCount();

    // mock rs.getMetaData()
    doReturn(rsmd).when(rs).getMetaData();

    return rs;
  }

  /**
   * Creates the mock ResultSet.
   *
   * @param columnNames the names of the columns
   * @param data
   * @return a mocked ResultSet
   * @throws SQLException
   */
  public static ResultSet create(
                         final String[] columnNames,
                         final Object[][] data)
                         throws SQLException {
    return new MockResultSet(columnNames, data).buildMock();
  }
}
Published on Java Code Geeks with permission by Fahd Shariff, partner at our JCG program. See the original article here: Java: Mocking a ResultSet using Mockito

Opinions expressed by Java Code Geeks contributors are their own.

(0 rating, 0 votes)
You need to be a registered member to rate this.
Start the discussion Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Leave a Reply

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
Notify of