存根方法不起作用:使用 Mockito 时,JDBC 语句尝试使用资源失败,NPE 失败



所以这是方法:

protected void writeData(String bucket, String key, String tableName) throws SQLException{
try {
Class.forName(DRIVER_NAME);
try (
Connection connection = DriverManager.getConnection(redshiftDBUrl, DBUtils.getConnectionProperties(redshiftDBUsername, redshiftDBPassword));
Statement statement = connection.createStatement();
){
String query = String.format(SQL_QUERY, tableName, bucket, key, redshiftIAMRole);
LOGGER.debug("query is: " + query);
statement.executeUpdate(query);
LOGGER.info("Copying to redshift done");
}
catch(SQLException ex){
LOGGER.error("Failed to write data to Redshift", ex);
throw new SQLException("Failed to write data to Redshift");
}
}catch (ClassNotFoundException ex) {
LOGGER.error("Unable to find the driver!", ex);
throw new SQLException(ex);
}
}

它在以下位置失败:

语句

语句 = connection.createStatement((;

下面是测试代码:

@Test 
public void testWriteDataWithValidData() throws SQLException{
PowerMockito.mockStatic(DriverManager.class);
Connection connection = mock(Connection.class);
PowerMockito.when(DriverManager.getConnection(REDSHIFT_DB_URL, REDSHIFT_DB_USERNAME, REDSHIFT_DB_PASSWORD)).thenReturn(connection);
Statement statement = mock(Statement.class);
when(connection.createStatement()).thenReturn(statement);
when(statement.executeUpdate(SQL_QUERY)).thenReturn(1);
ingestionRequestHandler.writeData(S3_BUCKET, S3_KEY, TABLE_NAME);
}

在测试课开始时,我有

@RunWith(PowerMockRunner.class)
@PrepareForTest(IngestionRequestHandler.class)

我认为按特定顺序进行嘲笑和存根可能很重要,因此将代码更改为:

PowerMockito.mockStatic(DriverManager.class);
Connection connection = mock(Connection.class);
Statement statement = mock(Statement.class);
when(connection.createStatement()).thenReturn(statement);
when(statement.executeUpdate(SQL_QUERY)).thenReturn(1);
PowerMockito.when(DriverManager.getConnection(REDSHIFT_DB_URL, REDSHIFT_DB_USERNAME, REDSHIFT_DB_PASSWORD)).thenReturn(connection);

但这也无济于事。

任何帮助将不胜感激。

您必须为被测类和DriverManager使用@PrepareForTest注释测试用例,例如

@PrepareForTest({DriverManager.class, IngestionRequestHandler.class})

有了该注释,以下测试将成功模拟DriverManager

@Test
public void testWriteDataWithValidData() throws SQLException {
PowerMockito.mockStatic(DriverManager.class);
Connection connection = Mockito.mock(Connection.class);
// you may prefer to provide explicit values for these next two parameters
String url = Mockito.anyString();
Properties usernameAndPassword = Mockito.any(Properties.class);
PowerMockito.when(DriverManager.getConnection(url, usernameAndPassword)).thenReturn(connection);
Statement statement = Mockito.mock(Statement.class);
Mockito.when(connection.createStatement()).thenReturn(statement);
// you may prefer to provide an explicit value from the base query and your bucket, key and tableName parameters
String sqlQuery = Mockito.anyString();
Mockito.when(statement.executeUpdate(sqlQuery)).thenReturn(1);
ingestionRequestHandler.writeData(S3_BUCKET, S3_KEY, TABLE_NAME);
}

最新更新