Unit testing 为什么不在单元测试中访问数据库?
我在博客上读到过这样的消息:当单元测试运行时,数据库不应该被击中。我理解这个理论,但是我说我有复杂的存储过程,这是业务域操作的一部分。我想为与业务操作相关的代码编写一组单元测试,但是如果我模拟数据库,我会觉得我并没有“真正”测试操作的所有部分。例如,有人可能会在某个数据库代码中创建一个bug,而测试仍然可以正常运行 我想知道这个关于单元测试的指南在实践中是否是好的。 我见过“集成测试”的概念,但是我不确定使用什么工具来进行集成测试。例如,使用Nunit这样的测试框架创建集成测试可以吗 谢谢Unit testing 为什么不在单元测试中访问数据库?,unit-testing,nunit,Unit Testing,Nunit,我在博客上读到过这样的消息:当单元测试运行时,数据库不应该被击中。我理解这个理论,但是我说我有复杂的存储过程,这是业务域操作的一部分。我想为与业务操作相关的代码编写一组单元测试,但是如果我模拟数据库,我会觉得我并没有“真正”测试操作的所有部分。例如,有人可能会在某个数据库代码中创建一个bug,而测试仍然可以正常运行 我想知道这个关于单元测试的指南在实践中是否是好的。 我见过“集成测试”的概念,但是我不确定使用什么工具来进行集成测试。例如,使用Nunit这样的测试框架创建集成测试可以吗 谢谢 Hu
Hugo在测试中处理数据库的问题是,数据库中的更改或代码中的更改可能会导致测试失败。单元测试通常应该尽可能直接地指向导致他失败的更改。 因此,如果要测试DB访问的代码,可以使用固定的测试数据库。通过这种方式,您可以确定访问数据库的代码是错误的,因为您知道数据库没有更改,如果您想更改数据库设置,请先更改测试数据库并看到测试失败,然后修复它,然后更改not test DB。 在我参与的一个项目中,我们创建了一个小数据库,在每次测试之前生成到内存中。“…当单元测试运行时,不应该命中数据库…”-当然,除非您正在对持久性对象进行单元测试
我不知道你在引用哪些博客,但我敢打赌他们说的是,在集成测试期间模拟某些组件可能会有好处。如果您已经对持久层进行了单元测试,则无需再次测试。在这种情况下,模拟的好处更多地与减少依赖性和不确定性有关。例如,您可能已经对代码进行了单元测试、打包,现在是时候将其迁移到更接近生产的环境中了。如果您需要的数据库不可用(例如,没有正确版本的架构,缺少您需要的数据,或者只是第一个到达那里的另一个应用程序需要的数据),您可以使用mock来允许您的集成测试毫不延迟地进行。单元测试没有命中数据库有两个主要原因:
- 你希望你的测试尽快进行
- 您希望将代码作为单个单元进行测试,而不是测试它如何与其他代码/数据库集成
在您的情况下,您需要测试存储过程。然后您需要编写一个运行这些存储过程的测试。您可以通过代码运行它们(集成测试),也可以直接从测试运行它们(类似于单元测试)。在这两种情况下,您都可以使用Nunit。好吧,问题是,如果您让您的单元测试命中数据库,那么您不仅仅是在测试单个代码单元,而是在命中多个代码单元,还有DAL、存储过程等。这就是为什么TDD支持者说不要在单元测试中命中数据库 这也是为什么你不应该在纯粹的、TDD概念化的、理论化的、神圣的UnitTEST中占有太多分量的原因。虽然单元测试本身并不是一件坏事,而且事实上对于确保程序员正确构建每个组件非常重要,但系统测试更为重要。总的来说,可能更难找到导致系统测试失败的确切方法,它们更现实,并且实际测试系统。
所谓的“组件测试”——更像是系统测试,但对于系统的一小部分,即端到端来说——在我看来是一个很好的折衷方案
(提示TDD现在反驳…:)你只是处于语义灰色地带
- 系统测试从端到端覆盖整个系统
- 单元测试可用于描述端到端循环的一个子段
- 测试更真实(使用实际数据库)
- 要编写的测试代码更少(不需要编写数据库的模拟)
- 在写入数据库访问层之前,测试无法运行
- 如果有bug或测试失败,您不知道bug是在代码中还是在数据库访问层中