使用Asp.Net Boilerplate进行单元测试时获取新的DbContext

时间:2014-12-18 05:03:36

标签: c# asp.net entity-framework unit-testing asp.net-boilerplate

我正在开发一个基于Asp.Net Boilerplate的项目,现在我必须使用真实数据库连接的真实存储库对服务进行单元测试(没有模拟)。我一直在https://gist.github.com/hikalkan/1e5d0f0142484da994e0中使用BringerOd的最后一篇文章作为设置我的UnitOfWorkScope实例的指南。所以,我的代码目前看起来像这样:

IDisposableDependencyObjectWrapper<IUnitOfWork> _unitOfWork;

[TestInitialize]
public void SetUpService()
{
    //initialize service

    _unitOfWork = IocManager.Instance.ResolveAsDisposable<IUnitOfWork>();
    UnitOfWorkScope.Current = _unitOfWork.Object;
    UnitOfWorkScope.Current.Initialize(true);
    UnitOfWorkScope.Current.Begin();

}

[TestCleanup]
public void CleanUpService()
{
    UnitOfWorkScope.Current.Cancel();
    _unitOfWork.Dispose();
    UnitOfWorkScope.Current = null;
}

这就像第一次单元测试的魅力一样,但当我尝试在第二次测试中进行存储库调用时,我得到:“操作无法完成,因为已经处理了DbContext。”

我的猜测是,当TestInitialize方法再次运行时,工作单元范围将被分配相同(处置)的DbContext,而不是新的。我想,在我的实际测试方法中,我可以使用IUnitOfWork在一个使用块内部设置UnitOfWorkScope。但是,我真的不想在每次测试中重复这种逻辑。有谁知道如何手动获取使用块的效果,以便每次都获得一个全新的DbContext?

1 个答案:

答案 0 :(得分:1)

检查:http://aspnetboilerplate.com/Pages/Documents/Repositories

您必须使用[UnitOfWork]属性标记调用方法。

原因如链接文件中所述

  

当您从存储库方法中调用GetAll()时,必须存在打开的数据库连接。这是因为IQueryable<T>的延迟执行。除非您调用ToList()方法或在foreach循环中使用IQueryable<T>(或以某种方式访问​​查询的项目),否则它不会执行数据库查询。因此,当您调用ToList()方法时,数据库连接必须处于活动状态。这可以通过使用[UnitOfWork] ASP.NET Boilerplate属性标记调用方法来实现。请注意,应用程序服务方法已默认使用[UnitOfWork],因此,GetAll()无需为应用程序服务方法添加[UnitOfWork]属性即可。