【问题标题】:How are people unit testing code that uses Linq to SQL [closed]人们如何对使用 Linq to SQL 的代码进行单元测试 [关闭]
【发布时间】:2008-09-09 19:13:59
【问题描述】:

人们如何对使用 Linq to SQL 的代码进行单元测试?

【问题讨论】:

  • 我只是在尝试使用 Linq2Sql 的 ASP.NET MVC,并尝试为“TaskList”演示应用程序编写一些单元测试。遇到非常奇怪的错误,然后我偶然发现了这个。看到如此简单的事情阻碍了一个伟大的技术堆栈,我感到非常难过。
  • 查看此答案,了解如何使用 LINQ to SQL 有效且成功地进行测试:stackoverflow.com/questions/4128640/…
  • 有足够多的查询部分可以与 linq 一起正常工作,而不能与 linq to sql 一起工作。如果我们有一种机制来测试 linq2sql 兼容性而不实际运行 SQL Server,那就太好了。(对于 SQL Server,其他 DBMS 的实现可能支持其他表达式转换)。当您想测试您的规范模式或 DSL 以组装查询部分(过滤器、转换、聚合)时,似乎别无选择,只能针对实际的数据库实例运行测试。或者有吗?

标签: linq unit-testing linq-to-sql


【解决方案1】:

更新:

Fredrik 在他的博客中提供了一个关于如何对 linq2sql 应用程序进行单元测试的示例解决方案。下载地址:

http://web.archive.org/web/20120415022448/http://iridescence.no/post/DataContext-Repository-Pattern-Example-Code.aspx

我认为他发布示例解决方案不仅很棒,而且他还设法为所有类提取接口,这使得设计更加解耦。

我的旧帖:

*我发现这些博客是制作 DataContext 包装器的良好开端: Link1 Link2

除了第一个实现了为表提取接口的方法之外,它们几乎涵盖了相同的主题。第二个比较广泛,所以我也包括在内。*

【讨论】:

  • 第一个链接的实际地址有误,复制粘贴地址看真正有用的文章。
  • 我能够在 Way Back Machine 上找到示例代码(zip 下载也可以)和 Link1,因此这些链接现在已修复。我找不到 Link2 的工作副本。
【解决方案2】:

晚了 3 年,但我就是这样做的:

https://github.com/lukesampson/LinqToSQL-test-extensions/

无需编写包装器或进行大量检查,只需将 T4 模板放在 .dbml 旁边即可:

  1. 数据上下文的接口,例如IExampleDataContext
  2. 用于数据上下文的内存模拟,例如MemoryExampleDataContext

两者都会自动使用您已在 DBML 中配置的映射。

所以你可以做类似的事情

public class ProductRepo {
    IExampleDataContext DB { get; set };
    public ProductRepo(IExampleDataContext db) {
        DB = db;
    }

    public List<Product> GetProducts() {
        return DB.Products.ToList();
    }
}

你可以用任何一个来调用它

new ProductRepo(new MemoryExampleDataContext()).GetProducts(); // for testing

new ProductRepo(new ExampleDataContext()).GetProducts(); // use the real DB

【讨论】:

  • 这是一个很棒的解决方案,效果很好,谢谢!它只是在接口中缺少存储过程。
【解决方案3】:

包装 DataContext,然后模拟包装器。这是完成它的最快方法,尽管它需要编码进行测试,有些人认为这很奇怪。但有时,当您的依赖项无法(轻松)模拟时,这是唯一的方法。

【讨论】:

    【解决方案4】:

    Linq 使测试变得更加容易。 Linq 查询在 Lists 上和在 Linq-to-sql 的东西上一样好。您可以将 Linq 换成 SQL 以获取列表对象并进行测试。

    【讨论】:

    • 问题在于外键关系(EntitySet/EntityRef)和列IsDbGenerated = true
    • 你真的必须小心这种方法。 Linq to SQL 和 Linq to Objects 是不同的提供程序,不能保证它们的操作完全相同(实际上,有时它们不会)。特别是在这种情况下,Linq to SQL 是 Linq to Objects 的子集。我预测会有许多绿色单元测试,然后是运行时失败。
    【解决方案5】:

    The Wayward Web Log 上的 Mattwar 有一篇很棒的文章,介绍了如何模拟可扩展的 Linq2Sql 数据上下文。看看——MOCKS NIX - AN EXTENSIBLE LINQ TO SQL DATACONTEXT

    【讨论】:

      【解决方案6】:

      通常,您不需要测试使用 LINQ to SQL 的代码部分,但如果您真的想要,您可以使用您在服务器上查询的相同数据集并将它们转换为 -内存对象并针对它运行 LINQ 查询(这将使用 Enumerable 方法而不是 Queryable)。

      另一种选择是使用 Matt Warren 的 mockable version of the DataContext

      您还可以通过调试器(从 IQueryable 对象)获取 LINQ to SQL 使用的 SQL 语句,手动检查这些语句,然后将它们包含在自动化测试中。

      【讨论】:

      • 为什么有人不需要测试使用 LINQ to SQL 的代码部分?我是例如编写一个 asp.net mvc 网页,其中许多控制器使用 LINQ to SQL,我必须测试这些控制器...
      • 我的意思是你不需要确保 LINQ to SQL 本身像宣传的那样工作(因为微软已经为你测试过),而不是你的代码使用来自 LINQ to SQL 的任何结果类。
      【解决方案7】:

      LINQ to SQL 实际上非常适合进行单元测试,因为它能够根据 DBML 中定义的内容动态创建数据库。

      通过 DataContext 创建 DB 并将其设置为空来测试 ORM 层非常好。

      我在我的博客上介绍了它:http://web.archive.org/web/20090526231317/http://www.aaron-powell.com/blog/may-2008/unit-testing-linq-to-sql.aspx

      【讨论】:

      • 我查看了作者当前的网站,找不到提到的帖子。自从上一个链接被破坏以来,我已经用我可以从 Way Back Machine 找到的最佳匹配编辑了答案。
      • 是的,该帖子似乎已在时间(以及多次迁移)中消失了。但实际上我在那里提出的解决方案不是单元测试,而是集成测试
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-20
      • 1970-01-01
      • 2012-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多