我应该对数据访问层进行单元测试吗?这是一种好的实践方法,如何实施?

14

如果我有一个数据访问层(例如nHibernate), 里面有一个名为UserProvider的类和一个业务逻辑层类UserBl,那么我是否应该测试它们的方法SaveUser或GetUserById,以及从BL层调用的DA层中的任何其他公共方法。这是一种冗余还是常见做法?

在单元测试中测试DA层是常见的吗?还是这属于集成测试领域?

使用测试数据库更好呢,还是在测试期间创建数据库数据更好呢?

任何帮助都将不胜感激。

4个回答

7

这个问题没有标准答案,取决于具体情况。有些人(例如Roy Osherove)认为只需测试带有条件逻辑(if语句等)的代码,这可能包括或者不包括您的数据访问层(DAL)。一些实行TDD的人则认为应该测试所有内容,包括DAL,并且目标是100%的代码覆盖率。

个人认为只有在其中存在逻辑时才测试它,因此最终会对一些DAL方法进行测试,而其他方法则不测试。大多数情况下,您只需检查业务逻辑是否调用了数据访问层,这种方法确实有一定优点,但我认为没有必要。它更有意义的做法是编写涵盖整个应用程序、包括数据库的集成测试,以包括GetUserById之类的内容。

无论你采用什么方法,你可能已经知道,但请确保你的单元测试不要触及真正的数据库。(这并不是什么问题,但那就是一个集成测试而不是一个单元测试,因为它需要更长时间和复杂的设置,并且应该分别运行)


这与我对 DAL 测试的观点非常相似。如果有任何逻辑并且你想确保它有效,就编写单元测试。总的来说,最好利用你的时间和精力设置针对实际数据库和已知测试数据的集成测试。 - Eric Pohl
1
SQL没有逻辑吗? - Pascal Thivent
1
@Pascal - 好的,我的SQL一般来说不需要测试,但我并不是说你不应该进行测试。但我不会将其作为数据访问层(DAL)的组成部分进行测试,它要么是一组单独的单元测试(可能使用不同的工具,例如DBFit),要么是集成测试的一部分。正如我所说,我认为“代码”单元测试不应触及数据库,因为设置复杂,存在潜在的环境问题(需要本地数据库或网络),而且会降低速度。 - Grant Crofton

1

为每个层编写单元测试是一个好习惯,即使是数据访问层(DAL)。

我认为在真实数据库上运行测试不是一个好主意,你可能会破坏重要的数据。我们过去常常设置一个数据库副本来进行测试,里面只有足够的数据来运行测试。 在我们的测试项目中,我们有一个特殊的web.config文件,其中包含测试设置,如连接到我们的测试数据库的ConnectionString。


1
根据我的经验,逐层测试并单独测试每个层次都很有帮助。将其集成并再次测试。集成测试通常无法测试所有方面。有时如果数据访问层(我不知道 nHibernate)是生成的代码或某种通用代码,它看起来可能过度。但我曾多次看到系统测试的回报。这是冗余吗?在我看来不是。这是常规做法吗?很难说。我在一些项目中看到过,但并非我参与的所有项目都有。这通常取决于团队/个人开发者的时间/资源和心态。
使用测试数据库好还是在测试期间创建数据库数据好?这是一个非常不同的问题。不能轻易回答。这取决于您的项目。创建一个新的很好,但有时会出现虚假的错误(虽然是错误)。这取决于您的项目(产品开发还是专有开发)。通常,在专有的现场开发中,数据库从某处迁移而来。因此,需要对迁移的数据进行第二次测试。但这更多地是在系统测试级别上。

0

如果数据访问层中有逻辑,比如使用相同的存储过程进行插入和更新,那么对DAL进行单元测试是值得的,知道插入是否有效、随后调用是否更新了先前的值并返回它而不是列表。在你的情况下,SaveUser方法可能首次进行插入,随后进行更新,单元测试阶段知道正在执行的操作很好。

如果你使用像iBatis或Hibernate这样的框架,其中可以实现类型处理程序,那么值得确认处理程序以符合底层数据库的方式处理值。

至于针对实际数据库进行测试,如果你使用Spring等框架,则可以利用支持的数据库单元测试类进行测试,并自动回滚事务,因此运行测试后数据库不会受到影响。点击这里了解详细信息。其他框架可能提供类似的支持。


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