Mocking Entity Framework to unit test your data services

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).

About Sorin Dolha

My passion is software development, but I also like physics.
This entry was posted in Architecture, C# and tagged , , , , , , . Bookmark the permalink.

Add a reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s