java - 如何模拟在构造函数中创建的类?

标签 java spring spring-boot junit spring-jdbc

假设我有一个 bean JdbcTemplate,并且在只有一次类中我需要显式 NamedParameterJdbcTemplate。它是在构造函数中创建的。

问题:如何在 junit 测试期间模拟它?

@Service
public class QueryService {
    private final NamedParameterJdbcTemplate namedJdbc;

    public BookingExportService(JdbcTemplate jdbc) {
        this.namedJdbc = new NamedParameterJdbcTemplate(jdbc);
    }

    public void sql() {
        namedJdbc.query(sql1, mapSqlParameterSource, resultSetExtractor);
        namedJdbc.query(sql2, mapSqlParameterSource, resultSetExtractor);
    } 
}

在这里定义模拟很困难,因为我必须模拟底层的 JdbcTemplate 调用。这可以按如下方式工作:

@MockBean
private JdbcTemplate jdbc;

@Test
public void testQuery() {
    when(jdbc.query(any(PreparedStatementCreator.class), any(ResultSetExtractor.class))).thenReturn(..);
}

但是:如果我有不同的 sql 查询应该产生不同的结果(如上面的 sql1 和 sql2),那么我就不走运了,在模拟期间不能区分 sql。

我的机会有多大?

最佳答案

这里:

this.namedJdbc = new NamedParameterJdbcTemplate(jdbc);

这只会让您的代码难以测试。基本上你在这里绕过了依赖注入(inject),好吧,这意味着:你对该字段内容没有任何控制权。

三个选项:

  • 转向像 PowerMock(ito) 或 JMockit 这样的模拟框架,它们允许您控制对 new() 的调用(不推荐)
  • 更改您的代码,例如使用构造函数伸缩...这样您就可以简单地传递该类的一个实例(然后可以轻松地使用 Mockito 等“普通”框架进行模拟)
  • 因为你已经在使用一个有自己的依赖注入(inject)想法的框架(例如@Autowired):退后一步,做一些框架暗示它要做的事情。

关于java - 如何模拟在构造函数中创建的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57392816/

相关文章:

java - stanford coreNLP 共指错误

java - init() : Couldn't get lock for/var/lib/tomcat6/./tm.out 中的 Atomikos 错误

java - 如何从多模块项目中启动 :run on root pom. xml

Java NullPointerException 与截断的堆栈跟踪

Java - 在 HashSet 中搜索对象的字段

java - Mockmvc put方法总是返回204状态

java - Spring security permit all 不适用于多个 url

java - 如何使用 JPA 存储库在具有组合 PK 的表中插入多条记录,并且其中一条记录是自动递增的?

Java:处理程序对于已检查的异常是必需的

java - springmvc显示页面问题