2012-03-21 196 views
14

我一直在寻找EasyMock和单元测试DAO类,用于“外部容器”测试的教程/示例。不过,我认为他们中的大多数都会谈论测试服务层,而不是模拟DAO类。我有点困惑,它是真的如何单元测试DAO层?DAO单元测试

有人会说,与DB &交互测试的EJB实际上是集成测试,而不是单元测试,但那么你怎么知道,如果你的SQL是正确的(假设没有ORM),并从你的DAO插入/查询正确的数据真正的(读取,与生产中的数据库类似的本地数据库)数据库?

我读到DBUnit是解决这种情况的解决方案。但我的问题是关于使用DBUnit“外部容器”之类的框架。如果DAO依赖于某些EJB,那么如何处理这些事务?如果触发器更新插入中的其他表,会发生什么情况?

什么是单元测试的最佳方式只测试具有这种依赖性的DAO?

回答

23

就我个人而言,我通过点击某种测试数据库来测试DAO,最好是您的应用程序在生产中使用的相同类型的数据库(显然不是相同数据库)。

我想如果你这样做,测试更多的是一个集成测试,因为它依赖于运行的数据库。这种方法的好处在于它尽可能接近正在运行的生产环境。它的缺点是你需要测试配置,你需要一个正在运行的测试数据库(本地到你的机器或你的环境中的某个地方),测试可能需要更长时间才能运行。您还需要确保在执行测试后回滚测试数据。

一旦DAOs被测试,绝对嘲笑他们单元测试您的服务。

1

我正在使用HSQLDB进行Dao和Service API测试。性能很好,它也支持交易。我没有使用EJB。我使用Hibernate。

有一些问题,我知道在不同的数据库上运行测试可能会掩盖一些受支持的数据库问题。但我认为这样的问题应该在烟雾&验收测试中被捕获。

问候, 高野

12

通常用的DAO的想法是让周围的数据访问代码的最小包装,所以什么都没有,除了映射到数据库进行测试,并与嘲笑单元测试是没用的。如果实际上DAO中有逻辑值得使用mock进行测试,那么可能会说您滥用DAO模式并且逻辑应该处于服务中。

用于测试映射到数据库DBUnit是有用的,因为它允许您在测试之前指定起始数据集,以便您的测试从已知状态开始,并且它允许您指定数据的结束状态应该是什么,所以你不必编写大量的单元测试代码来断言什么是预期的。

理想情况下,如果您有像Hibernate这样的工具将数据库抽象出来,您可以使用像H2或HSQLDB这样的内存数据库,这样您的测试运行得更快,并且不需要创建数据库。如果您必须使用真实的数据库,请确保您的测试具有自己的测试,以便他们可以创建和删除数据,而不会影响其他进程或受其他进程的影响。在实践中,本地和CI环境中都有一个数据库不太可能,并且使用内存数据库更加实用。

1

我最终定居编写,可以在容器外运行单元测试,用一个活生生的数据库和事务支持使用一个独立的事务管理器(Bitronix),我能够也回滚。我想这不会使测试纯单元测试仍然... ...很想听到你的意见人士在这种方法。

2

上的补充高野anwers,您可以使用HSQLDB进行DAO测试。我想你在你的项目中使用了Spring和Hibernate。您需要单独的配置文件指向HSQLDB,您需要在执行测试之前插入数据。对于使用HSQLDB可以做什么有一些限制,但一般用作查询和连接是可以的。有了这个解决方案可以在连续的环境中使用,例如jenkins。 集成测试可以使用HSQLDB,所以这部分不会被模拟。