您不能 - 如果單元測試意味着您在內存中使用虛假存儲庫,並且因此使用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