如何对扩展SqlMapClientDaoSupport的DAO进行单元测试

时间:2020-03-06 14:30:12  来源:igfitidea点击:

Spring DA帮助编写DAO。当使用iBATIS作为持久性框架并扩展SqlMapClientDaoSupport时,应为DAO设置SqlMapClient模拟,但我不能这样做。 SqlMapClientTemplate不是接口,EasyMock无法为其创建模拟。

解决方案

DAO和单元测试相处得不好!
在没有任何业务逻辑并且专注于数据库访问的组件中模拟任何内容都是没有意义的。
我们应该尝试编写集成测试。看看spring参考文档,第8.3章:http://static.springframework.org/spring/docs/2.5.x/reference/testing.html

试试Mockito。它允许模拟类,而不仅仅是接口。

这就是为什么我不从SqlMapClientDaoSupport扩展过来的原因。取而代之的是,我向SqlMapClientTemplate注入了依赖项(键入为SqlMapClientOperations接口)。这是一个Spring 2.5示例:

@Component
public class MyDaoImpl implements MyDao {

    @Autowired
    public SqlMapClientOperations template;

    public void myDaoMethod(BigInteger id) {
        int rowcount = template.update("ibatisOperationName", id);
    }
}

正如@Banengusk建议的那样,可以使用Mockito来实现。但是,重要的是要确保DAO将使用包装了模拟SqlMapClient的Spring SqlMapClientTemplate。实际上," SqlMapClientTemplate"将调用委派给IBatis层中的" SqlMapSession"。

因此,需要一些其他的模拟设置:

mockSqlMapSession = mock(SqlMapSession.class);
mockDataSource = mock(DataSource.class);

mockSqlMapClient = mock(SqlMapClient.class);
when(mockSqlMapClient.openSession()).thenReturn(mockSqlMapSession);
when(mockSqlMapClient.getDataSource()).thenReturn(mockDataSource);

dao = new MyDao();
dao.setSqlMapClient(mockSqlMapClient);

然后我们可以验证行为,如下所示:

Entity entity = new EntityImpl(4, "someField");
dao.save(entity);

ArgumentCaptor<Map> params = ArgumentCaptor.forClass(Map.class);
verify(mockSqlMapSession).insert(eq("insertEntity"), params.capture());
assertEquals(3, params.getValue().size());
assertEquals(Integer.valueOf(4), params.getValue().get("id"));
assertEquals("someField", params.getValue().get("name"));
assertNull(params.getValue().get("message"));