如何编写使用匿名内部类(如PreparedStatementSetter)的类的JUnit测试?

时间:2019-07-17 15:38:04

标签: java spring junit spring-test spring-test-mvc

我有以下使用匿名内部类(String result = Stream .of(map1.entrySet().stream().filter(e -> e.getValue()).map(Map.Entry::getKey).findFirst(), map2 .entrySet().stream().filter(entry -> entry.getValue().entrySet() .stream() .anyMatch(e -> e.getKey().contains("fruit") && e.getValue().stream().anyMatch( i -> i.equals("Pear")))) .map(Map.Entry::getKey) .findFirst()) .filter(Optional::isPresent).map(Optional::get).findFirst().orElse("NULL"); System.out.println("result: " + result); )的类,它使用new PreparedStatementSetter()来设置查询中的值并返回对象的PreparedStatementSetter

问题是我不确定如何为这种方法编写单元测试。 一旦单元测试到达调用它的行List,它就会跳到行尾,并且getJdbcTemplate().query(......)的值返回discAuditLogList,并且单元测试完成,没有任何错误。 当我查看null中的代码覆盖率时,所有IntelliJ语句都从未执行过。

ProductLogDao.java

ps.setString

ProductLogDaoTest.java

//bunch of setter getters here

public List<ProductLogDTO> getProductLogDetail(RequestDTO requestDTO) throws SQLException, DataAccessException {
    logger.info("Inside ProductLogDao.getProductLogDetail" + requestDTO);
    List<ProductLogDTO> productLogList = null;
    final Map<String, String> requestParamMap = requestDTO.getParameters();
    if ("custom".equalsIgnoreCase(requestParamMap.get("recordtype"))) {
        ProductLogList = getProductCustomDetail(senderFeeSql, requestParamMap);
        return ProductLogList;
    }
    return productLogList;
}


public List<ProductLogDTO> getProductCustomDetail(String senderFeeSql,
                                                          final Map<String, String> requestParamMap) throws SQLException {
    @SuppressWarnings("unchecked")
    List<ProductLogDTO> productLogList = getJdbcTemplate().query(senderFeeSql, new PreparedStatementSetter() {
        public void setValues(PreparedStatement ps) throws SQLException {
            /***************************************************************************************************************/
            //FOLLOWING STATMENTS NEVER GET EXECUTED BECAUSE THEY ARE WITHIN ANONYMOUS CLASS (new PreparedStatementSetter())
            /***************************************************************************************************************/
            ps.setString(1, requestParamMap.get("startDfId"));
            ps.setString(2, requestParamMap.get("startDfId"));
            ps.setString(3, requestParamMap.get("chanelId"));
            ps.setString(4, requestParamMap.get("chanelId"));
            ps.setString(5, requestParamMap.get("fromDateTime"));
            ps.setString(6, requestParamMap.get("toDateTime"));
            ps.setString(7, requestParamMap.get("fromDateTime"));
            ps.setString(8, requestParamMap.get("toDateTime"));
        }
    }, new ProductCustomRowMapper());

    if (null != productLogList && (productLogList.size() > 0)) {
        productLogList.get(0).setRecordtype("custom");
        productLogList.get(0).setRecordsFetched(productLogList.get(0).getRecordsFetched());
    }
    return productLogList;
}

2 个答案:

答案 0 :(得分:2)

永远不要在依赖对象内部创建对象实例,例如:new PreparedStatementSetter() 它几乎无法连接该类实例,并且您无法将其更改为模拟对象。 始终执行以下一项操作:

  1. 通过工厂对象方法调用(myBusinessFactoryInstance.createPreparedStatementSetter)创建这些类实例。比起更改工厂,您可以创建一个模拟。

  2. 在Spring中,您可以通过构造函数或setter方法注入此依赖项。

如果这样做,您的测试将很有趣。

答案 1 :(得分:0)

您已经嘲笑JdbcTemplate,但是还没有嘲笑JdbcTemplate方法。这就是为什么它返回null的原因。

您可以使用某种测试数据库。如果是Spring,则可以使用嵌入式的https://docs.spring.io/spring/docs/3.0.0.M4/spring-framework-reference/html/ch12s08.html。有关在测试过程中模拟数据库的更多信息,请参考以下问题:How to simulate a DB for testing (Java)?

无论哪种方式,您都可以检查Mockito的query()方法是否调用了verify()方法。