我需要模拟JDBC更新语句,并且我想确保发送的更新字符串是正确的。我有一个MockConnectionManager,它定义了以下定义预期查询字符串的方法:
public void setUpdateExpectedQuery(String ...expectedQueryStrings) throws SQLException {
Statement mockStatement = mock(Statement.class);
when(mockConnection.createStatement()).thenReturn(mockStatement);
when(mockStatement.executeUpdate(anyString())).then(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocationOnMock) throws Throwable {
String str = Arrays.toString(invocationOnMock.getArguments());
throw new RuntimeException("Update string is not as expected: " + str);
}
});
for(String expected : expectedQueryStrings) {
when(mockStatement.executeUpdate(expected)).then(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
// Do something, just don't throw an exception here.
return null;
}
});
}
}
我希望如果遇到意外的查询字符串,则会抛出异常。我们期望的查询字符串如Mockito wiki(http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#2)中所述。
出于某种原因,在执行测试并只调用setUpdateExpectedQuery时,会抛出异常。
MockConnectionManager connectionManager = (MockConnectionManager) context.getBean("connectionManager");
connectionManager.setUpdateExpectedQuery("INSERT WHATEVER INTO WHENEVER");
与第一个答案中写的相同的异常:java.lang.RuntimeException:更新字符串不符合预期:[INSERT WHATEVER INTO WHENEVER]
这怎么可能?正在调用'何时'实际调用该方法?我从来没有在其他情况下看到它......
答案 0 :(得分:2)
我怀疑问题是你在循环中的调用(当你调用mockStatement.executeUpdate(expected)
时)与先前的when(mockStatement.executeUpdate(anyString()))
模拟匹配。
请记住,模拟知道您在when
中调用的内容的方式是因为您正在调用它 - 想象将when(mockStatement.executeUpdate(anyString()))
翻译成:
int result = mockStatement.executeUpdate(anyString());
OngoingStubbing<Integer> tmp = when(result);
tmp.then(...);
您可能只需要进行单 when(...)
来电。所以:
public void setUpdateExpectedQuery(String ...expectedQueryStrings)
throws SQLException {
final Set<String> capturedQueries = new HashSet<>
(Arrays.asList(expectedQueryStrings);
Statement mockStatement = mock(Statement.class);
when(mockConnection.createStatement()).thenReturn(mockStatement);
when(mockStatement.executeUpdate(anyString())).then(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocationOnMock) throws Throwable {
String query = (String) invocationOnMock.getArguments[0];
if (capturedQueries.contains(query)) {
return null;
}
throw new RuntimeException("Update string is not as expected: " + query);
}
});
}