#java #unit-testing #mockito
#java #модульное тестирование #mockito
Вопрос:
Я пытаюсь выполнить модульное тестирование и написать тест для jdbctemplate.query
. Мне нужно покрытие кода для приведенного ниже метода.
Код:
` public List<User> UserInfo(final Long runId){
jdbcTemplate.setFetchSize(10);
List<User> userList = jdbcTemplate.query(con -> con.prepareStatement(GET_USER_INFO)
, (rs, rowNum) -> {
String userName = rs.getString("username");
String shoppingItems = rs.getString("shopingItems");
Long shoppingid = rs.getLong("shoppingid");
User user= new User();
user.setCmts(userName);
user.setNodeid(shoppingItems);
user.setNodename(shoppingid);
user.setRunId(runId);
return user;
});
return userList;
}`
Я написал тест, как показано ниже, но запуск теста «coverage as junit» не показывает мне никакого покрытия кода для метода, который находится внутри (rs, rowNum) -> {
Тест:
`@InjectMocks
private OracleRepository oracleRepository;
@Mock
private JdbcTemplate jdbcTemplate;
@Mock
private ResultSet rs;
@Mock
private Connection connection;
@Mock
private PreparedStatement stmt;
@Mock
private RowMapper rowMapper;
@Test
public void UserInfoTest() throws SQLException {
String username= "joe";
String shoppingItems= "3";
long shoppingId = 1123456778;
long runId = 2;
List<User> listUser = new ArrayList<User>();
Mockito.when(rs.getString("cmts")).thenReturn(cmts);
Mockito.when(rs.getString("node")).thenReturn(node);
Mockito.when(rs.getLong("nodeid")).thenReturn(nodeid);
User user= new User();
user.setUserName(username);
user.setShoppingItems(shoppingItems);
user.setShoppingId(shoppingId);
user.setRunId(runId);
listUser.add(user);
Mockito.when(connection.prepareStatement(Mockito.any(String.class))).thenReturn(stmt);
Mockito.when(rowMapper.mapRow(Mockito.any(ResultSet.class), Mockito.any(Integer.class))).thenReturn(user);
Mockito.when(jdbcTemplate.query(Mockito.anyString(), Mockito.any(RowMapper.class))).thenReturn(listUser);
List<User> list = oracleRepository.UserInfo(runId);
}`
Как мне решить эту проблему?
Ответ №1:
В нижней части вашего теста после List<User>
вы можете добавить:
ArgumentCaptor<RowMapper> argCaptor = ArgumentCaptor.forClass(RowMapper.class);
Mockito.verify(jdbcTemplate).query(Mockito.any(PreparedStatementCreator.class), argCaptor.capture());
RowMapper<User> rowMapper = argCaptor.getValue();
User userResult = rowMapper.mapRow(rs, -1);
verify(rs).getString("username");
verify(rs).getString("shopingItems");
verify(rs).getLong("shoppingid2");
assertEqual(cmts, userResult.getCmts());
Это фиксирует определенный вами функциональный интерфейс, затем вы вызываете его как действие для его тестирования. Я также проверил проверки и утверждения. Однако это не так просто понять, если кому-то еще когда-либо придется поддерживать эту кодовую базу. Возможно, вы захотите рассмотреть возможность создания класса, реализующего интерфейс, и протестировать его непосредственно на читаемость.