我正在开发一个基于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?
答案 0 :(得分:1)
检查:http://aspnetboilerplate.com/Pages/Documents/Repositories
您必须使用[UnitOfWork]属性标记调用方法。
原因如链接文件中所述
当您从存储库方法中调用
GetAll()
时,必须存在打开的数据库连接。这是因为IQueryable<T>
的延迟执行。除非您调用ToList()
方法或在foreach循环中使用IQueryable<T>
(或以某种方式访问查询的项目),否则它不会执行数据库查询。因此,当您调用ToList()
方法时,数据库连接必须处于活动状态。这可以通过使用[UnitOfWork]
ASP.NET Boilerplate
属性标记调用方法来实现。请注意,应用程序服务方法已默认使用[UnitOfWork]
,因此,GetAll()
无需为应用程序服务方法添加[UnitOfWork]
属性即可。