2010-10-25 59 views
1

当谈到TDD时,我仍然遇到了一个小问题。我将如何测试数据库逻辑?

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

做我:

一)首先插入测试记录,然后执行方法和测试结果

B)使用,可能是数据库中的数据。不要热衷于这种逻辑原因,它可能会导致事情中断。

c)你有什么建议?

回答

5

您应该选择选项a)。

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

+0

我在这里有一个问题,我现在正在编写代码插入记录以及编写代码返回记录。这使得代码基础翻番。有些东西可能会改变我如何插入记录。 – Neale 2010-10-25 08:26:43

+0

代码库“双打” - 但它是值得的,相信我!正如托马斯指出的那样,重复性至关重要。 – Marijn 2010-10-25 08:42:08

+1

插入数据的代码可以通过使用helper API(如dbUnit)来简化。这将为您将XML文档转换为数据库。 – 2010-10-25 12:36:37

4

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

+2

因为您正在使用Linq,所以您可以选择用'IQueryable <>'替换'ObjectSet <>'(当使用EF时),并用模拟/测试对象列表替换'IQueryable <>'您在执行测试时运行Linq查询。 – 2010-10-25 08:20:45

1

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

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

我成功地将这种方法用于我的NHibernate应用程序(howto 1 | howto 2 + nice summary),但我并不熟悉Linq2SQL。

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

有人认为使用数据库进行测试不是单元测试。使用ActiveRecord的模式时

  • 你可以有一个建筑/设计,其中数据库是很难模拟出,例如,或者当:无论如何,我相信有,你使用一个数据库,想自动化测试情况你使用LINQ2SQL(尽管在评论之一彼得回答一个有趣的解决方案)
  • 您要运行集成测试,与应用程序和数据库的完整体系
+0

我尝试过使用内存中的数据库,但启动和设置数据库的时间长于测试对现有(远程)Oracle实例运行的时间。第二个好处是可以手动检查测试失败的东西。 – 2010-10-25 12:41:32

+0

关于开始和设置时间:这可能确实是一个问题。使用NHibernate(Castle.ActiveRecord项目)我能够部分创建模式,省略那些未经测试的部分。 – Marijn 2010-10-25 15:43:22

+0

关于手动检查:我看到可能的优点,但在我看来,单元测试应该指出失败的原因,而不需要手动检查db。 – Marijn 2010-10-25 15:46:09

0

我已经做了过去:

  • 开始事务
  • 删除数据库中的所有表中的所有数据
  • 设置参考数据所有的测试需要
  • 设置你的数据库表所需要的测试数据
  • 运行测试
  • 中止事务

ŧ他的作品很好地提供了你的数据库没有太多数据,否则它很慢。所以你会希望使用测试数据库。如果您有一个控制良好的测试数据库,则可以在事务中运行测试,而无需先删除所有数据。


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

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