我愿意接受关于这个问题的更好标题的建议。
对于使用Entity Framework足够长的任何人来说,您必然会遇到生成的IQueryable<T>
无法由数据库执行的问题。这源于IQueryable<T>
除了内存实现(例如LINQ to objects)之外不可能完全实现的事实。诸如C#方法调用和使用Single
/ SingleOrDefault
作为非最终查询操作之类的事情在发送到真实IQueryProvider
时会导致失败(例如对于MSSQL或Oralce),但是通过在单元测试中。
我目前知道如何测试这些情况的唯一方法是实际运行该软件。虽然我同意该软件绝对应该作为编写新查询(或一般新代码)的一部分来完成,但如果使用单元测试可以找到这些类型的错误会很有帮助。导致我在这里的事件是发现了一个新的错误,我确信开发人员是一个无辜和安全的变化。更进一步,通过大量的单位测试给出了一种虚假的自信感。
是否可以验证生成的IQueryable<T>
实际上是否可以通过单元测试在特定的数据库技术(MSSQL,Oracle,等等)上运行?
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作为非最终查询操作,这将失败。
还有其他情况,但我认为以上两个例子描述了我试图能够检测到的内容。
答案 0 :(得分:1)
有了这个查询
var query =
from a in session.Query<A>
where a.Field == session.Query<B>().Single().Field
select a;
执行
query.ToString();
如果无法将其转换为正确的SQL查询,则会抛出异常。
答案 1 :(得分:0)
您必须模拟session.Query<A>
等属性,并在单元测试中发送enumerable\queryable
集合。根据我的经验,这样做的好处还不足以创建和维护这些类型的测试,特别是当您有涉及多个表和层的复杂查询时。
我发现有用(用于测试实际查询)是使用specflow
等框架进行更多集成测试,您可以使用它来轻松设置测试数据并执行集成测试,同时测试软件行为的级别高于单元测试。但是当然这些应该适用于真正的数据库,所以你可能不希望它们开始。