您不能 - 如果单元测试意味着您在内存中使用虚假存储库,并且因此使用LINQ to Objects。如果你使用LINQ to Objects来测试你的查询,你没有测试你的应用程序,而只测试你的假库。
你的例外是不太危险的情况,因为它表明你有一个红色测试,但可能实际上是一个工作应用程序。
更危险的是相反的情况:有一个绿色测试,但一个崩溃的应用程序或查询不会返回与您的测试相同的结果。查询像...
context.MyEntities.Where(e => MyBoolFunction(e)).ToList()
或
context.MyEntities.Select(e => new MyEntity { Name = e.Name }).ToList()
...将正常工作在您的测试,但不与LINQ到应用程序中的实体。
查询像...
context.MyEntities.Where(e => e.Name == "abc").ToList()
...可能会使用LINQ到对象比LINQ返回不同的结果实体。
您只能通过构建使用您的应用程序的LINQ to Entities提供程序和实际数据库的集成测试来测试此问题以及您的问题中的查询。
编辑
如果你仍然想编写单元测试,我想你一定假查询本身或在查询中至少表达式。我可以想象,沿着下面的代码线的东西可能工作:
为Where
表达创建的接口:
public interface IEntityExpressions
{
Expression<Func<MyEntity, bool>> GetSearchByDateExpression(DateTime date);
// maybe more expressions which use EntityFunctions or SqlFunctions
}
为应用程序创建一个实现......
public class EntityExpressions : IEntityExpressions
{
public Expression<Func<MyEntity, bool>>
GetSearchByDateExpression(DateTime date)
{
return e => EntityFunctions.TruncateTime(e.Date) == date;
// Expression for LINQ to Entities, does not work with LINQ to Objects
}
}
...并在单元测试项目的第二个实施:
public class FakeEntityExpressions : IEntityExpressions
{
public Expression<Func<MyEntity, bool>>
GetSearchByDateExpression(DateTime date)
{
return e => e.Date.Date == date;
// Expression for LINQ to Objects, does not work with LINQ to Entities
}
}
在你的类,你正在使用的查询创建这个接口和一个私人会员两个构造函数:
public class MyClass
{
private readonly IEntityExpressions _entityExpressions;
public MyClass()
{
_entityExpressions = new EntityExpressions(); // "poor man's IOC"
}
public MyClass(IEntityExpressions entityExpressions)
{
_entityExpressions = entityExpressions;
}
// just an example, I don't know how exactly the context of your query is
public IQueryable<MyEntity> BuildQuery(IQueryable<MyEntity> query,
SearchOptions searchOptions)
{
if (searchOptions.Date.HasValue)
query = query.Where(_entityExpressions.GetSearchByDateExpression(
searchOptions.Date));
return query;
}
}
使用第一个(默认)构造函数在您的应用程序:
var myClass = new MyClass();
var searchOptions = new SearchOptions { Date = DateTime.Now.Date };
var query = myClass.BuildQuery(context.MyEntities, searchOptions);
var result = query.ToList(); // this is LINQ to Entities, queries database
使用与FakeEntityExpressions
第二构造在单元测试:
IEntityExpressions entityExpressions = new FakeEntityExpressions();
var myClass = new MyClass(entityExpressions);
var searchOptions = new SearchOptions { Date = DateTime.Now.Date };
var fakeList = new List<MyEntity> { new MyEntity { ... }, ... };
var query = myClass.BuildQuery(fakeList.AsQueryable(), searchOptions);
var result = query.ToList(); // this is LINQ to Objects, queries in memory
如果您正在使用依赖注入容器,你可以通过注射,如果IEntityExpressions
相应的执行到构造利用它,不需要默认的构造函数。
我已经测试了上面的示例代码,它工作。
我已经删除了我的答案,这是不是对您有用。不知何故,我怀疑我没有告诉你任何新东西。我不知道如何在单元测试中处理您的查询,除非将整个查询放在单元测试中实现了LTO友好的接口('c => c.Date.Date == ...') 。 – Slauma 2012-03-06 16:13:48
您能否取消删除您的答案?我认为这是相当有效的,可以帮助其他人...... – 2012-03-06 16:19:04
该方法只是一个占位符。如果Linq to Entity转换器在看到此方法时处理表达式树,它知道如何用数据库特定的构造来替换它。因此该方法本身没有任何实现,但会抛出NotSupportedException。 – Pawel 2012-03-06 17:16:58