Marcin Drobik

software journeyman notes

Entity Framework Core InMemory

Entity Framework Core has support for InMemory database which is great help when writing tests against database.

However currently the setup of InMemory database is somewhat unobvious. To make it more readable I use class similar to this:

public class InMemoryDatabaseInstance<TContext> where TContext : DbContext
{
    public DbContextOptions<TContext> DbContextOptions { get; }

    public InMemoryDatabaseInstance()
    {
        DbContextOptions = new DbContextOptionsBuilder<TContext>()
            .UseInMemoryDatabase()
            .UseInternalServiceProvider(
                new ServiceCollection().AddEntityFrameworkInMemoryDatabase().BuildServiceProvider())
            .Options;
    }

    public static implicit operator DbContextOptions<TContext>(InMemoryDatabaseInstance<TContext> instance) => instance.DbContextOptions;
}

Thanks to implicit operator it's fairly easy to use it:

public void ShouldRetrieveNotices()
{
    var instance = new InMemoryDatabaseInstance<MyContext>();
    using (var db = new MyContext(instance))
    {
        db.Notices.Add(new Notice()
        {
            Title = "Test Notice",
            Deadline = DateTime.Now.AddDays(2)
        });

        db.SaveChanges();
    }

    using (var db = new MyContext(instance))
    {
        var notice = db.Notices.Single();
        Assert.Equal("Test Notice", notice.Title);
        Assert.Equal(DateTime.Now.AddDays(2), notice.Deadline);
    }
}

public class MyContext : DbContext
{
    public MyContext(DbContextOptions<MyContext> dbOptions) : base(dbOptions)
    {
    }

    // ...
}

comments powered by Disqus