使用Mockito模拟JdbcTemplate的DataSource

时间:2013-03-27 19:57:16

标签: java mocking datasource mockito jdbctemplate

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

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:2)

您无法做到这一点,因为您无法控制JdbcTemplate实施。您应该依赖注入JdbcTemplate,然后模拟JdbcTemplate

这个难点指出代码存在问题。您的代码取决于JdbcTemplate的具体实例。如果您在其上使用依赖注入,它将会更少耦合。


由于您不想修改受测试的系统,您可以这样做:

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

因此,您正在测试的课程将如下所示:

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);                
}

// ...