使用Mockito模拟JdbcTemplate的DataSource

我正在尝试在Spring项目中测试一个类。 我想在测试类和dao类中进行尽可能多的更改,这样我就不必因为更改而重新测试所有类型的东西。

我正在使用的类有一个JdbcTemplate template类变量,该变量由以下实例化:

 setJdbcTemplate(DataSource dataSource) { this.template = new JdbcTemplate(dataSource); } 

我想测试的方法使template.query()运行定义的SQL查询并将结果返回到列表。

我在我的测试用例中创建了以下内容,但我不确定如何使用它。 我可以使用Mockito使以下代码返回某个字符串列表吗?

 DataSource mockedDataSrc = Mockito.mock(DataSource.class); customerClassDao.setJdbcTemplate(mockedDataSrc); 

我可以以某种方式使用when或another命令来设置我想要返回到JdbcTemplate的.query调用的内容吗?

您无法执行此操作,因为您无法控制JdbcTemplate实现。 您应该dependency injectionJdbcTemplate然后模拟JdbcTemplate

这个困难指出了你的代码存在问题。 您的代码取决于JdbcTemplate的具体实例。 如果您在其上使用dependency injection,它将更少耦合。


由于您不想修改受测试的系统,因此可以执行以下操作:

更改template字段以使其受到包保护(即:删除private关键字)。 然后,在实例化您正在测试的类之后,我将其设置为mock(JdbcTemplate.class)。 现在,您将能够直接使用JdbcTemplate并在JdbcTemplate上进行validation。

所以你正在测试的类看起来像这样:

 public class SystemUnderTest { JdbcTemplate jdbcTemplate; public void setJdbcTemplate(DataSource dataSource) { this.template = new JdbcTemplate(dataSource); } } 

你的测试会做到这一点:

 @Before public void setUp() { SystemUnderTest sut = new SystemUnderTest(); sut.jdbcTemplate = mock(JdbcTemplate.class); } // ... 

如果您正在测试DAO,那么模拟数据源是没有意义的。 你在测试什么? 您需要创建一个与数据库交互的DAO。

一旦你有了这个工作,你就可以在测试使用它的服务时模仿基于接口的DAO。 你已经测试了DAO; 测试服务时没有理由重做它。

如果你在测试DAO时嘲笑数据源,我会说你偏离了轨道。