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

发布于 2024-07-05 23:45:37 字数 151 浏览 10 评论 0原文

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

Spring DA helps in writing DAOs. When using iBATIS as the persistence framework, and extending SqlMapClientDaoSupport, a SqlMapClient mock should be set for the DAO, but I can't do it. SqlMapClientTemplate is not an interface and EasyMock cannot creates a mock for it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

神经暖 2024-07-12 23:45:37

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

Try Mockito. It lets mock classes, not only interfaces.

不弃不离 2024-07-12 23:45:37

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

DAO and unit tests do not get along well !
That does not make sense to mock anything in a component that does not hold any business logic and is focused on database access.
You should try instead to write an integration test. Take a look at the spring reference documentation, chapter 8.3 : http://static.springframework.org/spring/docs/2.5.x/reference/testing.html

转身泪倾城 2024-07-12 23:45:37

这正是我不从 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);
    }
}

This exact reason is why I don't extend from SqlMapClientDaoSupport. Instead, I inject a dependency to the SqlMapClientTemplate (typed as the interface SqlMapClientOperations). Here's a Spring 2.5 example:

@Component
public class MyDaoImpl implements MyDao {

    @Autowired
    public SqlMapClientOperations template;

    public void myDaoMethod(BigInteger id) {
        int rowcount = template.update("ibatisOperationName", id);
    }
}
一杯敬自由 2024-07-12 23:45:37

正如 @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"));

As @Banengusk suggested - this can be achieved with Mockito. However, it is important to establish that your DAO will be using a Spring SqlMapClientTemplate that wraps your mock SqlMapClient. Infact, SqlMapClientTemplate delegates invocations to the SqlMapSession in the IBatis layer.

Therefore some additional mock setup is required:

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

We can then verify behaviour like so:

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"));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文