【问题标题】:ASP.NET MVC TDD with LINQ and SQL database带有 LINQ 和 SQL 数据库的 ASP.NET MVC TDD
【发布时间】:2009-01-06 14:12:46
【问题描述】:

我正在尝试通过测试开始一个新的 MVC 项目,我认为最好的方法是拥有 2 个数据库。 1 用于测试,1 用于我运行应用程序并使用它(也真正测试,因为它还没有生产)。

对于测试数据库,我正在考虑将创建表脚本和填充数据脚本放在测试设置方法中,然后在拆卸方法中删除所有这些。

虽然我将使用 Linq to SQL,但我认为这不会允许我这样做?

如果我想这样做,我是否只需要走 ADO 路线?还是应该只使用模拟对象并将数据存储为数组或其他东西?

关于最佳实践的任何提示?

Jeff 是如何为 StackOveflow 做这件事的?

【问题讨论】:

    标签: sql asp.net-mvc linq tdd


    【解决方案1】:

    我所做的是为 DataContext 包装器定义一个接口,并为 DataContext 使用包装器的实现。这使我可以在我的测试中使用替代的、假的 DataContext 实现(或者模拟它,如果更容易的话)。这完全从我的单元测试中抽象出数据库。我在http://andrewtokeley.net/archive/2008/07/06/mocking-linq-to-sql-datacontext.aspx 找到了一些入门代码,尽管我已经对其进行了扩展,以便它处理我的实体类上的验证实现。

    我还应该提到,我有一个单独的 QA 暂存服务器,因此可以对整个系统进行实时测试。我只是在单元测试中不使用实际的数据库。

    【讨论】:

      【解决方案2】:

      我查看了 tvanfosson 和 RikMigrations 的链接,在玩过他们之后,我更喜欢模拟数据上下文方法。我意识到我不需要一直创建表并删除它们。

      经过更多研究,我发现 Stephen Walther 的文章 http://stephenwalther.com/blog/archive/2008/08/17/asp-net-mvc-tip-33-unit-test-linq-to-sql.aspx 对我来说似乎更容易、更可靠。

      所以我将使用这个实现。

      感谢您的帮助。

      【讨论】:

        【解决方案3】:

        您可能希望找到其他方法来实际访问数据库以进行单元测试,因为这需要更多时间。话虽如此,您是否考虑过使用迁移来创建/删除表而不是使用 sql 脚本? RikMigrations 是我用来创建数据库的工具,因此我可以轻松地在一个地方修改所有代码。 Justin Etheredgeusing RikMigrations 上有一篇很棒的文章。

        【讨论】:

          【解决方案4】:
          【解决方案5】:

          我同意以上关于单元测试的大部分内容。但是,我认为重要的是要指出使用 Mock Repositories 和单元测试不会为您提供与 DB 集成测试相同级别的测试。

          例如,我们的数据库通常在架构中内置了级联删除。在这种情况下,删除聚合中的主要实体将自动删除所有子实体。但是,这不会自动应用于未由具有这些业务规则的物理数据库备份的模拟存储库(除非您将所有这些规则都构建到模拟中)。这很重要,因为如果有人出现并更改了我的架构设计,我需要它来破坏我的测试,以便我可以相应地调整代码/架构。我很欣赏这是集成测试而不是单元测试,但我认为值得一提。

          我的首选方案是创建一个包含示例数据(与您在 Mocks 中创建的数据类型相同)的主设计数据库。在每次测试运行开始期间,我都有一个自动化脚本,它创建 MasterDB 的备份并将其恢复到“TestDB”(我的所有测试都使用它)。这样,我在 Master 中维护一个干净的测试数据存储库,而不是在每次测试运行时重新创建自己。我的测试可以处理数据并测试所有需要的场景。

          当我调试应用程序时,我有另一个脚本可以备份 Master DB 并将其还原到 DEV 数据库。我也可以在这里处理数据,而不必担心丢失我的样本数据。由于等待重新创建数据库的延迟,我通常不会在每个会话中运行此特定脚本。我可能每天运行一次,然后全天玩/调试应用程序。例如,如果我在调试过程中删除表中的所有记录,我会在完成后运行脚本来重新创建 DevDB。

          这些步骤听起来会为流程增加大量时间,但实际上 - 它们不会。我们的应用程序目前有大约 3500 次测试,其中大约 3000 次在某个时间点访问数据库。每次测试运行开始时,数据库备份和恢复通常需要大约 10-12 秒。而且由于整个测试套件仅在 TFS 签入时执行,因此我们不介意是否必须再等一段时间。平均一天,我们的整个测试套件大约需要 15-20 分钟才能运行。

          我欣赏并接受集成测试比单元测试慢得多(因为需要使用真实数据库),但它更接近于“真实世界”的应用程序。例如,Mock Repositories 不会返回 DB 错误代码、不会超时、不会锁定、不会耗尽磁盘空间等。

          单元测试适用于简单的计算、基本的业务规则等,当然它们绝对是大多数不涉及数据库(或其他资源)访问的操作的最佳选择。但我不认为它们像集成测试那样有价值——人们经常谈论单元测试,但很少谈论集成测试。

          我希望那些对单元测试充满热情的人会为此大发雷霆。没关系 - 我只是想保持平衡,并提醒人们,充满已通过单元测试的项目在您在现场实施它们的那一刻仍然会严重失败。

          【讨论】:

          • 很有趣,但绝对偏离正题......再加上 TFS 的字母让我脊背发凉!
          【解决方案6】:

          本文给出了使用 typemock 模拟 linq to sql 的示例。

          http://blog.benhall.me.uk/2007/11/how-to-unit-test-linq-to-sql-and.html

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-04-03
            • 2011-08-27
            • 2011-07-21
            • 1970-01-01
            • 1970-01-01
            • 2015-05-10
            相关资源
            最近更新 更多