我尝试模拟一个查询,因为我使用rowmapper块作为输出。我为new RowMapper<Object>() {}
创建了一个块,在块内,我在映射中设置值并返回该映射。代码已成功运行,但是在代码覆盖范围内,我无法覆盖RowMapper块内的代码。
我尝试使用thenAnswer
覆盖该阻止,但出现异常
jdbcTempCPA.query(sql, new Object[] { orderNo, orderNo }, new RowMapper<Object>() {
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
ret.put("GetValue",
CommonUtil.correctNullString(rs.getString("SELECTED")));
ret.put("Indicator"
CommonUtil.correctNullString(rs.getString("ADVISORY_INDICATOR")));
return ret;
}
});
这是覆盖上面代码的junit代码
Mockito.when(jdbcTemplateMock.query(Mockito.anyString(), Mockito.any(Object[].class),Matchers.<RowMapper<Map<String, String>>>any())).thenReturn(ret);
答案 0 :(得分:0)
如果要对传递给模拟的参数做进一步的断言,则应使用captors。
如果您使用的是MockitoJUnitRunner
,则可以这样创建捕获器:
@Captor
private ArgumentCaptor<RowMapper<Object>> anyRowMapper;
此外,您还必须提供一个ResultSet
,最简单的方法也可能是对其进行模拟:
@Mock
private ResultSet resultSet;
在测试中,您现在可以编写:
// Set up mocks
when(resultSet.getString("SELECTED")).thenReturn("someString");
when(resultSet.getString("ADVISORY_INDICATOR")).thenReturn("someOtherString");
when(jdbcTemplate.query(anyString(), any(), any()).thenReturn(ret);
// Actually invoke your logic
service.doSomething();
// Capture arguments passed to jdbcTemplate.query(..)
verify(jdbcTemplate).query(anyString(), any(), anyRowMapper.capture());
现在您已经捕获了RowMapper
,就可以实际调用它了。考虑到此RowMapper
本身返回了ret
,您可以像这样为它编写进一步的断言:
Map<String, String> ret = anyRowMapper.getValue().mapRow(resultSet, 123);
assertThat(ret).contains(
entry("GetValue", "someString"),
entry("Indicator", "someOtherString")
);
这是最美丽的测试吗?考虑到模拟的数量,可能不会。在这种情况下,您可能需要编写一个集成测试,然后对带有测试数据的虚拟数据库运行代码。