【发布时间】:2008-09-21 09:06:52
【问题描述】:
Spring DA 有助于编写 DAO。当使用iBATIS作为持久化框架,扩展SqlMapClientDaoSupport时,应该为DAO设置一个SqlMapClient mock,但是我做不到。 SqlMapClientTemplate 不是接口,EasyMock 无法为其创建模拟。
【问题讨论】:
标签: java spring ibatis easymock
Spring DA 有助于编写 DAO。当使用iBATIS作为持久化框架,扩展SqlMapClientDaoSupport时,应该为DAO设置一个SqlMapClient mock,但是我做不到。 SqlMapClientTemplate 不是接口,EasyMock 无法为其创建模拟。
【问题讨论】:
标签: java spring ibatis easymock
DAO 和单元测试不能很好相处! 在不包含任何业务逻辑且专注于数据库访问的组件中模拟任何内容是没有意义的。 您应该尝试编写集成测试。看看 spring 参考文档,第 8.3 章:http://static.springframework.org/spring/docs/2.5.x/reference/testing.html
【讨论】:
这正是我不从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 将使用 Spring SqlMapClientTemplate 包装您的模拟 SqlMapClient。事实上,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"));
【讨论】:
试试Mockito。它允许模拟类,而不仅仅是接口。
【讨论】: