如何模拟实例化为局部变量的类

时间:2008-10-24 13:11:07

标签: java unit-testing tdd mocking

我正在为一个调用某些DAO类来执行数据库操作的业务方法编写测试。

此方法首先从DataSource对象检索JDBC连接,同一连接传递给所有DAO实例,因此我可以使用它来控制事务。所以,如果一切正常,我必须在连接对象上调用commit()。

我想测试是否调用了commit(),所以我想创建一个期望(我正在使用JMock)来检查它。但由于Connection类不是我的Business类的直接邻居,我不知道如何做到这一点。

有人知道如何克服这个问题吗?有一些JMock工具,或者一些替代设计可以克服这个问题吗?

由于

6 个答案:

答案 0 :(得分:3)

您需要模拟DataSource Connection,以便模拟DataSource返回您的模拟Connection。是的,这种事情最终成为一种真正的痛苦......

答案 1 :(得分:3)

我很难从你的描述中准确地告诉你的类是如何编写的,但是DataSource应该通过它的构造函数或setDataSource()方法注入你的DAO类。

这将允许您单独测试DAO,并允许您在单元测试中构建模拟DataSource并将其传递给正在测试的DAO。

答案 2 :(得分:1)

重构,以便将Connection注入Dao并将Dao注入到业务类中。然后,您可以模拟Dao和/或Connection。您可以轻松编写自己的模拟,扩展Connection并覆盖connect()以设置一个布尔值,稍后您可以通过写入方法(如wasConnectCalled())来检索。

答案 3 :(得分:1)

我肯定会建议您使用spring-jdbc而不是尝试自己编写此类代码。这将确保正确关闭连接,语句和结果集。 Spring还具有出色的事务管理功能,因此您无需担心这一点。

例如,使用spring-jdbc:

查看这个典型的更新语句
public void updateName(int id, String name) {
    getJdbcTemplate().update(
            "update mytable set name = ? where id = ?", 
            new Object[] {name, new Integer(id)});
}

答案 4 :(得分:0)

使bussines类从全局/静态对象工厂中检索局部变量。这样你就可以将工厂置于测试模式并使其返回模拟对象而不是真实对象。

那应该成功。

答案 5 :(得分:0)

@Paul借调。一旦你将连接的管理分开了,你就可以在你传递给拥有连接的东西的回调中写下剩下的行为 - 比如UnitOfWork。连接所有者处理事务,并将连接传递给UnitOfWork。交易在一个地方 - 易于测试,UnitOfWork在另一个地方,使用模拟连接进行测试。