Application testing
.NET Core C# Entity Framework Core NUnit SQL TDD Visual Studio

How to Unit Test .NET Core Applications With In-Memory Data Providers

Welcome to today’s post.

The topic of this post is in-memory providers in .NET Core applications and their use when unit testing.

The use of in-memory providers is most valuable when implementing unit tests and a connection to a cut-down database that mirrors the schema of the physical SQL database.

In a pre .NET Core environment (.NET Framework 4.6 and before), we would have to make use of any number of third-party providers that were installed from NuGet to provide in-memory functionality.

When is the best scenario to use in-memory data providers when testing?

In-memory data providers are more useful when we want to create tests with mock data using the same database schema as our test or production databases and an ORM provider such as Entity Framework Core.  

When are in-memory data providers not so useful?

The following scenarios are not suitable for in-memory unit testing:

  1. Using an existing test database for more realistic real-world test data OR
  2. Use a higher quantity of data to perform stress testing OR
  3. Integration testing using large databases.

I will now explain how to utilize the in-memory provider for .NET core.

With .NET core, there are no additional NuGet packages or external libraries required to use the in-memory feature after installing the Entity Framework Core package. We just include the namespace Microsoft.EntityFrameworkCore.

To use the in-memory provider in your unit test class, declare the namespace:

using Microsoft.EntityFrameworkCore.InMemory

To setup the in-memory provider, you will need to add a data context to your application’s ServiceCollection as follows:

services.AddDbContext<ApplicationDbContext>(options =>
    options.UseInMemoryDatabase("In_Memory_Db")
);

Where

ApplicationDbContext is your database context.

In_Memory_Db is the name of your in-memory database.

To retrieve the context of your in-memory data store use the following code snip:

serviceProvider = services.BuildServiceProvider();
context = serviceProvider.GetRequiredService
   <ApplicationDbContext>();

Using the in-memory provider through the data context is straightforward. Below is an example of data insertion and testing the data count:

var book = new BookViewModel() { 
    ID = 1, 
    Author = "W.Smith", 
    Title = "Rivers Run Dry", 
    YearPublished = 1954 
};
context.Add(book);
context.SaveChanges();

int bookCount = context.Books
    .CountAsync()
    .GetAwaiter()
    .GetResult();

var result = books.GetResult();
Assert.AreEqual(1, result.Count);

We can implement a significant number of data related unit tests with the in-memory data provider, however where the in-memory data provider may not provide us with testing coverage is with code that uses SQL objects directly, including the following:

  1. Stored procedure calls.
  2. Raw SQL queries.
  3. Database DDL operations.

This is expected, even with unit test frameworks such as Moq or NMock we cannot avoid having to mock out code that depend on SQL data object access. Where our code base does not reference SQL data directly, we can maximize test coverage fully using the Entity Framework Core ORM provider. All unit tests for SQL objects should then be moved into an integration test project as they are external dependencies.

The main benefit of the in-memory data provider is allowing our data dependent codebase where possible to be refactored and increase its test coverage.

That’s all for today’s post.

I hope this post has been informative and useful.

Social media & sharing icons powered by UltimatelySocial