DAO(又名存储库)是不是应该进行单元测试?

Posted

技术标签:

【中文标题】DAO(又名存储库)是不是应该进行单元测试?【英文标题】:Should DAOs (aka Repositories) be unit tested?DAO(又名存储库)是否应该进行单元测试? 【发布时间】:2011-01-16 16:52:32 【问题描述】:

任何存储库/DAO 实现中值得测试的部分是查询。 为确保这些查询正确,您必须在 实际数据库。

鉴于上述事实,对 DAO/存储库进行单元测试是否有意义?如果是,最佳做法是什么?

【问题讨论】:

【参考方案1】:

我非常虔诚地对我的存储库进行单元测试。实际上,它们可能是我最重要的单元测试。

如果您使用诸如 NHibernate 之类的 ORM,这实际上会非常轻松。

我使用包含 setup 和 teardown 的基本夹具来创建内存中的 sqlite db,然后在每次测试结束时将其销毁。这出奇的快。然后对于每个存储库,我都有一个为我的测试注入测试数据的设置。这是非常独立的,可以捕获我的存储库查询中的所有逻辑问题。

它唯一没有捕捉到的是数据库提供者特定的情况,但是当使用像 NHibernate 这样的东西时,这些通常是例外。

对于测试数据库特定查询的特殊情况,您可能需要一套使用不同设置和拆卸方法的测试。不幸的是,这些测试会比您的其他单元测试更慢并且可能更脆弱(这就是为什么它们应该组合在一起)。

如果您正在测试的数据库软件的“快速”版本可用,我仍然建议您在本地即时设置数据库,以便您始终确保运行测试的数据库具有他们期望的架构。不过,我会更改其中的一部分设置和拆卸。我只会在整个测试运行的开始和结束时设置和拆除数据库。然后每个测试设置和拆卸都应该启动一个事务,然后在最后回滚。这是在测试之间进行划分的一种快速方法。您最不想要的就是让一个测试中的数据影响另一个测试。

【讨论】:

我确实使用 Hibernate (Java),但我的应用程序使用一堆本机 SQL 来利用其他服务器上不可用的少数 Oracle 特定语句。 当我需要使用特定的某人而不仅仅是内存测试时,我添加了一些关于我过去所做的事情的信息。我宁愿不必这样做,因为它需要更多的工作,但它仍然可以相对轻松地完成。【参考方案2】:

是的 - 使用内存数据库(例如HSQLDBL)

This blogpost of mine 讨论了一个类似的话题。

更新:关于您的评论 - 在我链接的帖子中,ORM 用于确保数据库不一致不是问题。首先使用原始 SQL 并不是一个好主意(如果使用 OOP)。然后,您总是可以尝试尽可能使用 ANSI SQL(而不是测试不一致之处)。

另一种选择可能是专用一个测试数据库服务器 + 一个持续集成引擎,并且只在引擎内运行测试(这样来自多台机器的多个测试执行不会相互混淆)

【讨论】:

由于大多数 RDBMS 服务器在处理 SQL 的方式上彼此不同,我们如何确保它可以在我们的生产服务器上运行,因为它在内存数据库上运行,反之亦然? 如果你想确保一切正常,那么你还需要做集成测试 投了一个有用的答案。但是,不能单独使用 ANSI SQL。 :(【参考方案3】:

是的,必须对 DAO 层进行单元测试。在 java 中有像 dbUnit 这样的框架可以帮助你做到这一点。使用一些引导数据在数据库中保留一个单独的架构/实例将有助于您进行正确的单元测试,并且您可以涵盖大多数场景。

【讨论】:

以上是关于DAO(又名存储库)是不是应该进行单元测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中对 DAO 应用单元测试

对使用 Spring JDBC 的 DAO 类进行单元测试

用spring对hibernate daos进行单元测试

spring mvc中的单元测试

使用 XCode 3 对 iPhone 静态库进行单元测试

Android 单元测试 LiveData.value 返回 null