It’s not easy to write unit tests for services that use DbContext and DbSet<T> classes from Entity Framework (or Entity Framework Core), and there are complex solutions to approach this, like separating the data access layer completely, as I propose in my UnitOfWork-EntityFramework implementation.
However, there are faster solutions, more appropriate to many projects, like this one that I’ve just published to GitHub:
- Define a DbSetWrapper<T> over DbSet<T> and extract the interface you are actually using from it (too bad DbSet doesn’t already come with an associated IDbSet<T>);
- Wrap your DbContext-inheriting class (the one ending in DatabaseEntities) into a MyContextWrapper class defining and wrapping the properties type IDbSetWrapper<T> for each properties (tables) in the database model and ensure you properly implement IDisposable there; extract an IMyContext interface from it;
- Define a MyContextProvider class with extracted IMyContextProvider interface to return an IMyContext; the default implementation should simply create a new MyContextWrapper instance;
- In the unit test project define a DbSetMock<T> helper implementing IDbSet<T> and wrapping an internal in-memory list of objects instead of an actual DbSet;
- Finally, in unit tests, you can mock IMyContextProvider to return objects from preconfigured Mock<IMyContext> instances as needed (optionally custom DbSetMock<T> collections of mock data object instances), and pass that provider mock’s object to the tested service (to replace the default/dependency injected MyContextProvider instance it would normally use).