如何在没有数据库的情况下验证LINQ可查询

mha*_*and 7 c# linq unit-testing entity-framework iqueryable

注意:

我对这个问题有更好的标题的建议持开放态度.


背景:

对于使用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();
Run Code Online (Sandbox Code Playgroud)

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


可单独查询

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

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


还有其他情况,但我认为以上两个例子描述了我试图能够检测到的内容.

AD.*_*Net 0

您必须模拟属性,例如session.Query<A>并发送enumerable\queryable在单元测试中根据我的经验,这样做的好处不足以创建和维护此类测试,特别是当您有涉及多个表和层的复杂查询时。

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