Mocking Entity Framework to unit test your data services

arrows box business chalk

Photo by Pixabay on

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