Статьи

Java: макетирование ResultSet с использованием Mockito

Этот пост показывает, как вы можете java.sql.ResultSet используя Mockito Его можно использовать для помощи модульному тестированию кода, который выполняет операции с ResultSet (например, ResultSetExtractor ), не полагаясь на внешний источник данных.

Вы можете создать MockResultSet , предоставив список имен столбцов и двумерный массив данных. Например:

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

Код для MockResultSet показан ниже (также доступен в моем репозитории GitHub ). Обратите внимание, что я только издевался над несколькими методами, такими как next , getString и getObject но довольно легко getObject остальные, следуя тому же шаблону.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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();
  }
}
Опубликовано на Java Code Geeks с разрешения Фахда Шарифа, партнера нашей программы JCG . Смотрите оригинальную статью здесь: Java: Mocking a ResultSet с использованием Mockito

Мнения, высказанные участниками Java Code Geeks, являются их собственными.