如何对 ResultSetExtractor 进行单元测试?

Dix*_*vey 0 java junit unit-testing mockito

我需要有关在使用 jdbc 时如何对 ResultSetExtractor 进行单元测试的建议。

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);
  }
Run Code Online (Sandbox Code Playgroud)

通过上述使用匿名类的方法,我将不得不使用 argumentCaptor 来获取 ResultSetExtractor。到目前为止,我的测试如下。在 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);
  }
Run Code Online (Sandbox Code Playgroud)

我不知道使用匿名类是否会使单元测试变得更加困难。我总是可以从 jdbc 调用中提取匿名类并创建一个如下所示的类,但我不知道从哪里开始测试这个类。

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;
    }
  }
Run Code Online (Sandbox Code Playgroud)

下面的测试将通过任一实现,但我想避免使用 any(ResultSetExtractor.class)。如果可能的话,我想要的是测试 extractData(final ResultSet rs) 的实际实现。

@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));
  }
Run Code Online (Sandbox Code Playgroud)

Iva*_*van 5

您可以执行以下操作

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);
}
Run Code Online (Sandbox Code Playgroud)