DbContext, Dbset Mocking - C# made easy
No need to use repository pattern for just to test database queries.
Introduction
Entity Framework Core is a popular Object-Relational Mapping (ORM) framework used by so many .NET developers for interacting with databases. One of the challenges we as developers face while unit testing code that interacts with databases is that they often need to set up a test database or use a mocking framework to isolate the code being tested from the database.
N.B: If you use a repository pattern just for this then you should check this out.
Moq.EntityFrameworkCore is a popular mocking library that can be used to mock Entity Framework Core DbContext and DbSet classes, making it easier to unit test code that interacts with databases.
N.B: I am using Moq as my mocking framework and this is an extension package.
Setting up Moq.EntityFrameworkCore
Before we can use Moq.EntityFrameworkCore
, we need to install the NuGet package. We can do this by running the following command in the Package Manager Console:
Install-Package Moq.EntityFrameworkCore
Or add this to the csproj:
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="Moq.EntityFrameworkCore" Version="7.0.0.2" />
Once we have installed the package into our test project, we can start mocking DbContext and DbSet classes.
Mocking DbContext
To mock the DB context we need to add this:
var dbContextMock = new Mock<DbContext>();
Using the mocked DbContext and DbSet in tests
So there is no need to mock the dbset, the library will do this for us. We just need to configure the dbset return. Let's use it:
var service = new MyService(dbContextMock .Object);
var entities = Enumerable.Empty<DbSet>();
dbContextMock.Setup(x=> x.DbSet).ReturnsDbSet(entites);
var result = service.DoSomethingWithEntities();
Assert.AreEqual(2, result.Count);
Yahoo, that's it. Let's dissect it
In this example, we are testing a service that uses a DbContext to interact with a database. We create a mock DbContext and set dbset them up to return a loaded/empty list of MyEntity objects by using the ReturnsDbSet extension method. We then pass the mock DbContext to the service being tested and call a method that retrieves entities from the database.
Finally, we check that the method returned the expected number of entities.
Conclusion
Moq.EntityFrameworkCore is a powerful mocking library that can be used to isolate code being tested from the database. By using Moq.EntityFrameworkCore, developers can easily set up mock DbContext and DbSet classes, making it easier to write unit tests for code that interacts with databases.
I have created a fully functional demo focusing on all the relevant use cases on GitHub. If you have any confusion, please check this out. Run this command and see this for yourself.
git clone --single-branch --branch dbset-mock
https://github.com/purkayasta/Stories.git
Happy Testing. ๐