I need advice on how to unit test a ResultSetExtractor when using jdbc.
String sql = "SELECT * FROM item where item_id = ?";
return (Item) jdbcTemplate.query(sql, new ResultSetExtractor<Item>() {
@Override
public Item extractData(final ResultSet rs) throws ... {
if (rs.next()) {
Item item = new Item (rs.getString(1), rs.getString(2));
return item ;
} else
return null;
}
}, itemId);
}
With the above approach of using an anonymous class, I would have to use argumentCaptor to get the ResultSetExtractor. The test I have so far is below. I don't know how what to do next in terms of the ResultSetExtractor.
@Test
public void testGetItemByID() {
ArgumentCaptor<ResultSetExtractor> rseCaptor = ArgumentCaptor.forClass(ResultSetExtractor.class);
ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);
String sql = "SELECT * FROM item where item_id = ?";
itemDAOImpl.getItemByID(testId);
verify(mockJdbcTemplate, times(1)).query(stringCaptor.capture(), rseCaptor.capture(), stringCaptor.capture());
assertEquals(stringCaptor.getAllValues().get(0),sql);
assertEquals(stringCaptor.getAllValues().get(1),testId);
}
I dont know if using an anonymous class would make it harder to unit test. I could always pull the anonymous class out of the jdbc call and make a class like below, but I dont know where to start testing this class.
public class ItemResultSet implements ResultSetExtractor<Item> {
@Override
public Item extractData(ResultSet rs) throws ...{
if (rs.next()) {
Item item = new Item (rs.getString(1), rs.getString(2));
return item ;
} else
return null;
}
}
The test below would pass with either implementations but I want to avoid using any(ResultSetExtractor.class). What I want is to test the actual implementation of extractData(final ResultSet rs) if possible.
@Test
public void testGetItemByID() {
String sql = "SELECT * FROM item where item_id = ?";
when(mockJdbcTemplate.query(anyString(), any(ResultSetExtractor.class), anyString()))
.thenReturn(testItem);
assertEquals(testItem, itemDAOImpl.getItemByID(testId));
}
You could do the following
private ResultSet getMockResultSet() throws Exception {
ResultSet rs = Mockito.mock(ResultSet.class);
Mockito.when(rs.next()).thenReturn(true).thenReturn(false);
Mockito.when(rs.getString(1)).thenReturn("Value 1");
Mockito.when(rs.getString(2)).thenReturn("Value 2");
return rs;
}
private ResultSet getEmptyMockResultSet() throws Exception {
ResultSet rs = Mockito.mock(ResultSet.class);
Mockito.when(rs.next()).thenReturn(false);
return rs;
}
@Test
public void testDataExists() {
Item item = new ResultSetExtractor<Item>() {
@Override
public Item extractData(final ResultSet rs) throws ... {
if (rs.next()) {
Item item = new Item (rs.getString(1), rs.getString(2));
return item ;
} else
return null;
}
}.extractDatae(getMockResultSet());
assertEquals(item.getFirst(), "Value 1");
assertEquals(item.getSecond(), "Value 2");
}
@Test
public void testNoDataExists() {
Item item = new ResultSetExtractor<Item>() {
@Override
public Item extractData(final ResultSet rs) throws ... {
if (rs.next()) {
Item item = new Item (rs.getString(1), rs.getString(2));
return item ;
} else
return null;
}
}.extractData(getEmptyMockResultSet());
assertNull(item);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.