我有一个从结果集创建字符串的函数。还有发送信息的那个。你可以在
下面看到它们public String createStringReport(ResultSet resultSet) throws SQLException{
StringBuilder reportData = new StringBuilder("");
int columns = 0;
if(resultSet.getMetaData() != null) {
columns = resultSet.getMetaData().getColumnCount();
while (resultSet.next()) {
for (int i = 1; i <= columns; i++) {
reportData.append(resultSet.getString(i)).append("t");
}
reportData.append("n");
}
}
return !reportData.toString().isEmpty() ? reportData.toString() : "No data";
}
private void sendStringReport(String reportData) {
for (User u: users) {
sender.send(u, reportData);
log.info("send report - " + report.getName() + " to" + u.getName());
}
}
我需要写一个测试调用sender与参数字符串,这是之前生成的。这就是我现在的内容:
@Test
public void shouldGenerateStringReportWhenThreadRunHasData() throws SQLException {
String result = "somestring";
Report report = getReport(ReportType.STRING);
ReportCreator reportCreator = new
StringReportCreator(report, users, sender, dataSource, unexpectedErrorCounter);
when(resultSet.getString(anyInt())).thenReturn(result);
when(resultSet.next()).thenReturn(true).thenReturn(false);
int columns = 2;
final ResultSetMetaData rsmd = mock(ResultSetMetaData.class);
when(resultSet.getMetaData()).thenReturn(rsmd);
doReturn(rsmd).when(resultSet).getMetaData();
StringBuilder reportData = new StringBuilder("");
if(resultSet.getMetaData() != null) {
while (resultSet.next()) {
for (int i = 1; i <= columns; i++) {
reportData.append(result).append("t");
}
reportData.append("n");
}
}
reportCreator.run();
verify(sender, Mockito.times(users.size())).send(any(User.class), eq(reportData.toString));
}
不幸的是,我被告知:
Argument(s) are different! Wanted:
telegramSender.send(
<any reportbot.entity.User>,
"somestring somestring
somestring somestring
"
);
-> at ru.phoenixdnr.reportbot.ReportCreatorTest$Run.shouldGenerateStringReportWhenThreadRunHasData(ReportCreatorTest.java:233)
Actual invocations have different arguments:
telegramSender.send(
User(id=1, idTelegram=2, name=892e0f69-c10e-4961-b22e-11de333fbb55, email=73507828-9c7a-4026-8599-5e6c8c62e3c7),
"No data"
);
为什么reportData为空?我该如何解决这个问题?我已经试了一个星期了,但是一点用都没有。
问题似乎是你:
- 设置模拟结果集,
- 在构建预期输出时读取结果,
- 使用相同的结果集调用您要测试的方法。
当测试中的方法运行时,它发现结果集已经耗尽(或者至少.next()
返回false
),因此没有更多的数据可以从中读取。因此你得不到任何数据。
如果生成预期文本的代码使用单独的结果集,则不会出现此问题。
解决这个问题的一种方法是将所有ResultSet
模拟设置代码移动到一个单独的方法中,该方法创建并返回模拟ResultSet
。这样,您就可以调用此方法两次以获得两个不同的模拟ResultSet
,一次用于创建用于创建预期结果的结果集,另一次用于传递给报表创建器。
另一个修复是在不使用模拟ResultSet
的情况下生成预期的输出。您知道ResultSet.getMetaData()
不会返回null
,因此没有必要进行空检查,并且您还知道模拟ResultSet
中有多少行,因此可以用for
循环替换while
循环。
您错过了嘲笑ResultSetMetadata
的getColumnCount
呼叫:
when(rsmd.getColumnCount()).thenReturn(2);