如何在TestNG中使用Mockito模拟jdbc连接和结果集



我必须编写一些单元测试,但我在模拟ResultSet和jdbc Connection时遇到问题。

我有这个方法:

@Test
public void test3() throws SQLException, IOException {
    Connection jdbcConnection = Mockito.mock(Connection.class);
    ResultSet resultSet = Mockito.mock(ResultSet.class);
    Mockito.when(resultSet.next()).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(false);
    Mockito.when(resultSet.getString(1)).thenReturn("table_r3").thenReturn("table_r1").thenReturn("table_r2");
    Mockito.when(jdbcConnection
            .createStatement()
            .executeQuery("SELECT name FROM tables"))
            .thenReturn(resultSet);
    //when
    List<String> nameOfTablesList = null;
    try {
        nameOfTablesList = Helper.getTablesName(jdbcConnection);
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    //then
    Assert.assertEquals(nameOfTablesList.size(), 3);
}

错误显示在第 executeQuery("SELECT name FROM tables") 行中,听起来像这样:

java.lang.NullPointerException HelperTest.test3(HelperTest.java:71)

知道出了什么问题吗?

您需要

jdbcConnection.createStatement() 创建期望

默认情况下,我相信会返回一个null

应该读成这样:

ResultSet resultSet = Mockito.mock(ResultSet.class);
Mockito.when(resultSet.next()).thenReturn(true).thenReturn(true).thenReturn(true).thenReturn(false);
Mockito.when(resultSet.getString(1)).thenReturn("table_r3").thenReturn("table_r1").thenReturn("table_r2");
Statement statement = Mockito.mock(Statement.class);
Mockito.when(statement.executeQuery("SELECT name FROM tables")).thenReturn(resultSet);
Connection jdbcConnection = Mockito.mock(Connection.class);
Mockito.when(jdbcConnection.createStatement()).thenReturn(statement);

在这个低级别上模拟JDBC API是相当乏味的,因为你应该真正考虑嘲笑整个JDBC API。仅举几个例子:

  • 如果有人打电话给ResultSet.previous()会怎样?
  • 如果有人打电话给ResultSet.getObject()而不是getString(),会发生什么?
  • 如果ResultSet是通过Statement.getResultSet()获得的,会发生什么?

对于客户端代码,是否以一种或另一种方式调用 JDBC 并不重要,结果应该始终相同。如果你真的必须模拟数据库(而不是使用例如测试数据库,或者更好的是基于testcontainers的方法),那么使用jOOQ的MockDataProviderMockFileDatabase的东西肯定会让事情变得简单得多。在您的情况下:

MockDataProvider db = new MockFileDatabase(
    "SELECT name FROM tables;n"
  + "> namen"
  + "> --------n"
  + "> table_r3n"
  + "> table_r1n"
  + "> table_r2n"
  + "> @rows: 3n");
//when
List<String> nameOfTablesList = null;
try {
    nameOfTablesList = Helper.getTablesName(new MockConnection(db));
} catch (SQLException e) {
    e.printStackTrace();
}
//then
Assert.assertEquals(nameOfTablesList.size(), 3);

无论Helper.getTablesName()方法如何处理传递的 JDBC Connection,上述方法都将起作用。

请注意,我在jOOQ背后的公司工作,所以这个答案是有偏见的。

相关内容

  • 没有找到相关文章

最新更新