Sometimes we struggle to unit test our repositories due to creating a record in the database, now with EF-Core In-Memory Database; you can test your repository with ease. We have created a small dummy project to demonstrate to you the same.
In-Memory Database
An In-Memory Database is a lightweight, fast database that resides entirely in memory. It’s particularly useful for unit testing because it allows you to simulate database operations without the overhead of a real database. EF Core provides an In-Memory Database provider that you can use to test your data access code.
To set up in-memory databases and unit testing with C#, EF Core, and xUnit; follow these steps.
- 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.
Code is also available on Github: https://github.com/arpitsdotnet/RepositoryUnitTestingExample