我想测试使用Entity Framework构建的实体。 我的担忧是使用Entity Framework意味着直接处理数据源。 那么,有什么方法可以对基于Entity Framework的组件进行单元测试吗?
我想测试使用Entity Framework构建的实体。 我的担忧是使用Entity Framework意味着直接处理数据源。 那么,有什么方法可以对基于Entity Framework的组件进行单元测试吗?
<add name="DrinksEntities"
connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient
;provider connection string="Data Source=localhost\sqlexpress;Initial Catalog=Drinks2;Integrated Security=True;MultipleActiveResultSets=True;Application Name=EntityFramework""
providerName="System.Data.EntityClient" />
例子:单元测试连接字符串:
<add name="DrinksEntities"
connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient
;provider connection string="Data Source=.\SQLEXPRESS;attachdbfilename=|DataDirectory|\Inventory.mdf;Integrated Security=True;user instance=True;MultipleActiveResultSets=True;Application Name=EntityFramework""
providerName="System.Data.EntityClient" />
如果您想了解更多细节,请联系我。
我同意,你需要一个模拟框架。你可以创建“模拟”对象,这些对象不是从数据源中检索出来的,并且你可以测试该对象中的数据。我个人一直在使用Moq,并且我很喜欢它——还有Rhinomocks等其他框架。
在这个问题上我曾经非常沮丧,但现在我终于找到了一个解决方案,至少对于其中的一部分问题我感到很满意。
首先使用一个类似于仓库接口的东西:
public interface IRepository
{
IQueryable<T> GetObjectSet<T>();
}
public interface IQuery<T>
{
IQueryable<T> DoQuery(IQueryable<T> collection);
}
[TestMethod]
public void TestQueryFoo()
{
using(var repo = new SqlRepository("bogus connection string"))
{
var query = new FooQuery(); // implements IQuery<Foo>
var result = query.DoQuery(repo.GetObjectSet<Foo>()); // as long as we don't enumerate the IQueryable EF won't notice that the connection string is bogus
var sqlString = ((System.Data.Objects.ObjectQuery)query).ToTraceString(); // This will throw if the query can't be compiled to SQL
}
}
第二组单元测试可以自由地测试您的业务逻辑,而不必担心SQL编译步骤,这是我们遇到最多问题的地方。
尽管它并不完美,触发器显然不会被运行,DB实现的约束可能会被违反,并且上下文和数据库不同步的一些问题可能会出现。因此,虽然仍然需要端到端的集成测试,但有可能在简单的单元测试中捕获IMO最常见的运行时问题。
这里是工作单元模式+内存数据库+t4代码生成的聚合,用于自动生成虚假的EF dbContext。
http://mockingcompetence.wordpress.com/2013/05/20/fakingefdatacontext/
目前在完全复制真实的EF数据库连接时存在一些问题(无效的linq to EF查询和没有外键强制执行)。
然而,拥有一个内存上下文以快速运行单元测试几乎是进行TDD或任何其他种类的单元测试中心方法所必需的。
随着我解决更多问题,我将在上述链接中发布更新。