当上下文被抽象时,单元测试项目是否应该引用EF dll



我正在抽象我的DbContext,试图解决关注点分离问题,并使我的代码单元可测试。为了做到这一点,我想出了以下界面。

下面的此接口托管在名为AllInterfaces的程序集中。由于以下声明中的IDbSet,此项目引用了EF dll。

public interface ISalesContext : IDisposable   
{   
IDbSet<Customer> Customers { get; }   
IDbSet<Order> Orders { get; }   
IDbSet<Product> Products { get; }    
}    

我还创建了一个伪数据库集,如下所示。

public class FakeDataSet<T> : IDbSet<T> where T: class, new()
{
.......
}

因此,对于我的Customer对象,这个伪数据集如下所示。

public class FakeCustomerDbSet : FakeDbSet<Customer>
{
..............
}

然后我创建了我的假上下文如下。

public class FakeSalesContext : ISalesContext 
{
public FakeSalesContext ()
{
Customers = new FakeCustomerDbSet ();
}
public IDbSet<Customer> Customers { get; set; }
public IDbSet<Order> Orders{ get; private set; }
public IDbSet<Product> Products { get; private set; }
public void Dispose()
{
}
}

以上所有与伪对象相关的类(FakeDataSet、FakeCustomerDbSet和FakeSalesContext)都位于程序集中AllFakes。我不得不添加对EF dll的引用,因为IDbSet接口也在这些伪类中被引用。

然后我有了我的单元测试项目,我使用假对象来执行单元测试。

ISalesContext Context = new FakeSalesContext ();
Context.Customers.Add(new Customer() { Id = 1, LastName = "Karen" } );

问题是,这个单元测试要求我添加对实体框架dll的引用。如果我删除EF引用,我会得到以下编译错误。

类型"System.Data.Entity.IDbSet"1"是在程序集中定义的未被引用。必须添加对程序集的引用'EntityFramework,版本=4.4.0.0,区域性=中性,PublicKeyToken=b77a5c561934e089'。

如果我从AllFakes程序集中删除EF dll引用,我会得到以下错误。

找不到类型或命名空间名称"IDbSet"(您是缺少using指令或程序集引用?)

向所有这些程序集添加对EF dll的引用有意义吗?对我来说,既然我已经抽象了数据库上下文,这里就不需要它了。关于如何做到这一点,有什么建议吗?

我认为您需要对EF dll的引用。您确实对上下文进行了抽象,但您的抽象仍在使用EntityFramework.dll中定义的IDbSet接口。FakeSalesContext公开IDbSet类型的公共属性,如果您不添加对EntityFrameworkdll的引用(其中定义了IDbSet),则不会编译,因为编译器将不知道IDbSet是什么。

在这种情况下,我认为它没有问题。只要您只测试DbContext实现,引用本身只用于上下文对象的依赖关系解析。

最新更新