Java中测试Service/DAO层的工具和方法

5

我正在尝试找出测试Service和DAO层的最佳方法。因此,有几个子问题...

  1. 在测试Service层时,是最好对Mock DAO层进行测试还是对指向测试环境的“实际”DAO层进行测试?
  2. 当DAO层的唯一测试数据库位于共享环境(Oracle/DB2)中时,应如何测试DAO层中的SQL。
  3. 如何解决DAO写入/更新需要使用DAO读取进行测试的悖论,而DAO读取也必须进行测试?

我正在寻找任何关于这个领域的好文档、文章或参考资料以及任何帮助自动化过程的工具。我已经知道JUnit用于单元测试和Hudson用于CI。

2个回答

4

获取《Growing Object-Oriented Software, Guided by Tests》,它提供了关于如何测试数据库访问的一些很好的提示。

个人而言,我通常将DAO测试分为两部分:使用模拟数据库进行功能测试的单元测试和针对数据库执行查询的集成测试。如果您的DAO只有数据库访问代码,则不需要单元测试。

该书中提出的建议之一是(集成)测试必须提交更改到数据库中。在使用Hibernate并发现测试被标记为回滚且数据库从未收到插入语句后,我学会了这样做。如果您使用触发器或任何类型的验证(甚至是外键),我认为这是必须的。

另外一件事,要远离dbunit,它是一个很好的框架来开始工作,但当项目变得不再微小时,它就变得非常困难。我的偏好是有一组测试数据构建器类来创建数据,并将其插入到测试的设置或测试本身中。
并且检查dbmigrate,它不是用于测试,但它将帮助您管理升级和降级数据库模式的脚本。
在共享DB服务器的情况下,我为每个环境创建了一个模式/用户。由于每个开发人员都拥有自己的“本地”环境,因此他也拥有一个模式。

3
以下是我的回答:

以下是我的回答:

  1. 使用模拟DAO来测试您的服务。这样做更容易,更快捷。使用EasyMock或Mockito或其他任何模拟框架来测试服务层。
  2. 为每个开发人员提供自己的数据库架构以执行其测试。这些模式通常为空:单元测试在运行测试之前使用小型测试数据集填充数据库,并在测试完成后将其清空。使用DBUnit进行此操作。
  3. 如果读取操作针对一个明确定义的静态测试数据集(应该进行单元测试),那么您可以依赖它们来进行写入操作的单元测试。但是您也可以使用临时查询甚至使用DBUnit来测试写入操作是否按预期工作。测试的顺序并不重要。如果所有内容都通过,则一切正常。

+1 对于工具和建议。你对Augusto关于DBUnit的评论有反驳吗? - Andrew White
DBUnit 有其特点,但如果您坚持每个单元测试类使用一个数据集(而不是所有测试使用一个大数据集),那么它是可管理的。我必须说,我没有尝试过同一级别的任何其他工具,但 DBUnit 对于我而言在一个相当大的项目上运作良好。 - JB Nizet
也许我的说法有点严厉,但我发现DBunit的问题在于它很难重构。我曾经和4个非常优秀的开发人员一起工作,在频繁更改架构的项目中。不幸的是,Eclipse在进行这些重构方面并不好用,因此我们不得不手动更新DBunit文件(每个测试类都有一个数据集)。我认为Intellij在这方面可能会更好,但我不确定。 - Augusto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接