We occasionally find it difficult to unit test our repositories because of the process of establishing a record in the database. However, with the EF-Core In-Memory Database, testing your repository is now simple. To show you the same, we have made a little dummy project.

In-Memory Database

A lightweight, quick database that runs exclusively in memory is called an in-memory database. Because it lets you imitate database operations without the overhead of an actual database, it's especially helpful for unit testing. You can test your data access code using the In-Memory Database service offered by EF Core.

Use these instructions to build up in-memory databases and unit testing using xUnit, EF Core, and C#.

Set Up Your Project

  • Ensure you have the necessary NuGet packages installed.
    • `Microsoft.EntityFrameworkCore.InMemory`
    • `xUnit`
    • `xUnit.runner.visualstudio`
    • `Microsoft.NET.Test.Sdk`
  • Configure In-Memory Database: In your test project, configure the in-memory database in your DbContext options. This allows you to use an in-memory database for testing purposes.
  • Create Your DbContext: Define your DbContext class as you would for any EF Core application.
  • Write Unit Tests: Use xUnit to write your unit tests. You can create a test class and use the [Fact] attribute to define individual test methods.
  • Initialize the In-Memory Database in Tests: In your test methods, initialize the in-memory database and seed it with test data if necessary.
  • Run Your Tests: Use the xUnit test runner to execute your tests and verify the behavior of your code.

Here’s a high-level overview of the process.

Install Packages
dotnet add package Microsoft.EntityFrameworkCore.InMemory
dotnet add package xunit
dotnet add package xunit.runner.visualstudio
dotnet add package Microsoft.NET.Test.Sdk


Configure DbContext
public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
    public DbSet<User> Users { get; set; }
}


Write Unit Tests
public class UserRepositoryTests
{
    [Fact]
    public void Create_ShouldReturnSuccess_WhenDataGiven()
    {
        int expectedUserId = 1;
        string expectedUserName = “Test”;

        var options = new DbContextOptionsBuilder<ApplicationDbContext>()
            .UseInMemoryDatabase(databaseName: new Guid.NewGuid().ToString())
            .Options;

        using (var context = new ApplicationDbContext(options))
        {
            // Arrange: Seed data into the context
            context.Users.Add(new User { Id = expectedUserId, Name = expectedUserName });
            context.SaveChanges();

            // Act: Perform the action to be tested
            var actualUser  = context.Users.FirstOrDefault(e => e.Id == expectedUserId);

            // Assert: Verify the result
            Assert.NotNull(result);
            Assert.Equal(expectedUserName, actualUser.Name);
        }
    }
}


This setup allows you to test your EF Core code using an in-memory database, ensuring your tests are fast and isolated from your production database.

Output

Benefits and Limitations
Benefits

  • Speed: In-memory databases are faster than real databases.
  • Isolation: Tests are isolated from each other, ensuring no side effects.
  • Simplicity: Easy to set up and use.

Limitations
Not a Real Database: It doesn’t enforce all constraints (e.g., foreign keys) like a real relational database.
Limited Features: Some database-specific features may not be supported.