Getting new DbContext when unit testing with Asp.Net Boilerplate

1.9k Views Asked by At

I'm working on a project built on Asp.Net Boilerplate, and now I have to unit test the services using the real repositories with a real database connection (no mocking). I've been using the last post of BringerOd in https://gist.github.com/hikalkan/1e5d0f0142484da994e0 as a guide for setting up my UnitOfWorkScope instance. So, my code currently looks something like this:

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;
}

This works like a charm for the first unit test, but when I try to make a repository call in a second test, I get: "The operation cannot be completed because the DbContext has been disposed."

My guess is that when the TestInitialize method runs again, the unit of work scope is getting assigned with the same (disposed) DbContext, rather than a new one. I suppose, inside my actual test methods, I could set up my UnitOfWorkScope inside a using block with the IUnitOfWork. However, I really don't want to repeat that logic inside inside every single test. Does anyone know how to manually get the effect of a using block so that I get a brand new DbContext each time?

1

There are 1 best solutions below

0
On

Check: http://aspnetboilerplate.com/Pages/Documents/Repositories

You must mark the calling method with [UnitOfWork] attribute.

The reason for this, as explained in the linked document is

When you call GetAll() out of a repository method, there must be an open database connection. This is because of deferred execution of IQueryable<T>. It does not perform database query unless you call ToList() method or use the IQueryable<T> in a foreach loop (or somehow access to queried items). So, when you call ToList() method, database connection must be alive. This can be achieved by marking caller method with the [UnitOfWork] attribute of ASP.NET Boilerplate. Note that Application Service methods are already using [UnitOfWork] as default, so, GetAll() will work without adding the [UnitOfWork] attribute for application service methods.