【问题标题】:How to validate LINQ queryable without database如何在没有数据库的情况下验证 LINQ 可查询
【发布时间】:2016-09-15 10:25:01
【问题描述】:

注意:

我愿意为这个问题提供更好的标题。


背景:

对于任何使用 Entity Framework 足够长的人来说,您一定会遇到生成的IQueryable<T> 无法被数据库执行的问题。这是因为IQueryable<T> 不可能完全实现,除非是内存中的实现,例如 LINQ to objects。诸如 C# 方法调用和使用 Single/SingleOrDefault 作为非最终查询操作之类的事情在发送到真正的 IQueryProvider(例如 MSSQL 或 Oralce)时可能会导致失败,但会通过单元测试。

我目前知道如何测试这些情况的唯一方法是实际运行该软件。虽然我同意该软件绝对应该作为编写新查询(或一般的新代码)的一部分来完成,但如果可以使用单元测试找到这些类型的错误,那将是有帮助的。将我带到这里的事件是从我确信开发人员那里发现了一个新错误,尽管这是一个无辜且安全的更改。更进一步,大量通过单元测试给人一种错误的自信感。


问题:

是否可以通过单元测试验证生成的IQueryable<T> 实际上可以在特定的数据库技术(MSSQL、Oracle 等)上运行?


示例:

可通过 C# 方法调用查询:

var result = (
    from a in session.Query<A>
    where a.Field == SomeFunction(a)
    select a
    ).ToList();

由于数据库无法执行 C# 代码的明显原因,这将失败。


可单查询

var result = (
    from a in session.Query<A>
    where a.Field == session.Query<B>().Single().Field
    select a
    ).ToList();

由于使用 single 作为非最终查询操作,这将失败。


还有其他情况,但我认为以上两个示例描述了我想要检测的内容。

【问题讨论】:

  • 我们使用需要干净的数据库设置的“单元测试”。我们的测试设置插入测试数据,而拆卸将其删除。它们不是真正的单元测试,因为它们需要数据库连接,但它们也不是完整的功能测试。
  • @GendoIkari 这些测试称为集成。
  • @mhand 我不知道答案。但是您的问题是我在 SO 中见过的准备最充分的问题。希望这个问题能给你一些想法stackoverflow.com/questions/6599805/unit-test-iqueryable
  • @mhand 还有看看这个codeproject.com/Tips/1036630/…
  • 我们在实体框架和assert the query and logic is valid.joel.net/… 顶部有存储库模式

标签: c# entity-framework linq unit-testing iqueryable


【解决方案1】:

有这个查询

var query = 
    from a in session.Query<A>
    where a.Field == session.Query<B>().Single().Field
    select a;

执行

query.ToString();

如果不能翻译成正确的 SQL 查询,则会抛出异常。

【讨论】:

  • 有趣的方法。我看到的主要问题是它需要访问IQueryable&lt;T&gt; 实例。我想我有点希望IQueryProvider 的实现可以在生成时检查可查询对象
  • 如果您关心这里,它不会运行实际查询。
【解决方案2】:

您必须模拟session.Query&lt;A&gt; 之类的属性,并在单元测试中发送enumerable\queryable 集合。以我的经验,这样做的好处不足以创建和维护这些测试,特别是当您有涉及多个表和层的复杂查询时。

我发现有用的是(用于测试实际查询)更多的是使用 specflow 等框架进行的更多集成测试,您可以使用它们轻松设置测试数据并执行集成测试,同时从比单元测试更高的级别测试软件行为.但是当然这些应该在真实的数据库上工作,所以你可能不希望它们开始。

【讨论】:

    猜你喜欢
    • 2019-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 2021-09-25
    • 2018-10-26
    • 1970-01-01
    • 2020-01-10
    相关资源
    最近更新 更多