我如何单元测试数据库逻辑?

时间:2010-10-25 08:11:27

标签: c# unit-testing

在谈到TDD时,我仍遇到一个小问题。

我需要一种方法,从数据层(linq2SQL)获取一定数量的过滤数据记录集。请注意,我正在使用从DBML生成的linq生成的类。现在的问题是我想为此写一个测试。

做我:

a)首先在测试中插入记录,然后执行方法并测试结果

b)使用可能在数据库中的数据。不要热衷于这种逻辑,因为它可能导致事情破裂。

c)你有什么建议吗?

4 个答案:

答案 0 :(得分:5)

您应该选择选项a)。

单元测试应该是可重复的,并且必须完全由您控制。因此,为了使测试有意义,测试本身必须为执行准备数据 - 只有这样才能依赖测试结果。

答案 1 :(得分:4)

使用testdatabase并在每次运行测试时清除它。或者您可以尝试创建一个模拟对象。

答案 2 :(得分:1)

当我使用数据库运行测试时,我通常使用内存中的SQLite数据库。 使用内存db通常可以使测试更快。 此外,它很容易维护,因为关闭连接后数据库“已经消失”。

在测试设置中,我设置了db连接,并创建了数据库模式。 在测试中,我插入测试所需的数据。 (你的选择a)) 在测试拆解中,我关闭了与db的连接。

我在NHibernate应用程序(howto 1 | howto 2 + nice summary)中成功使用了这种方法,但我对Linq2SQL并不熟悉。

关于运行SQLite和Linq2SQL的一些指针都在SO(link 1 | link 2)上。

有些人认为使用数据库的测试不是单元测试。无论如何,我相信在某些情况下您需要使用数据库进行自动测试:

  • 您可以拥有一个架构/设计,数据库难以模拟,例如使用ActiveRecord模式时,或者当您使用Linq2SQL时(尽管在Peter的回答中有一个有趣的解决方案) )
  • 您希望使用完整的应用程序和数据库系统
  • 运行集成测试

答案 3 :(得分:0)

我过去做过的事情:

  • 开始交易
  • 删除数据库中所有表格中的所有数据
  • 设置所有测试所需的参考数据
  • 在数据库表中设置所需的测试数据
  • 运行测试
  • 中止交易

如果您的数据库中没有太多数据,这很有效,否则很慢。所以你希望使用一个测试数据库。如果您有一个受到良好控制的测试数据库,您可以在事务中运行测试,而无需先删除所有数据。


尝试设计您的系统,因此您可以模拟大多数测试的数据访问层。 单元测试数据库代码是有效的(通常很有用),但是对其他代码的单元测试不需要触及数据库。

您应该考虑是否可以从“端到端”系统测试中获得更多好处,仅针对您的“逻辑”代码进行单元测试。这在很大程度上取决于项目中的其他因素。