3

I have a bunch of test where I use the new UseInMemory function in EF7. When I run them all some of them fail. When I run them single they all pass. My best guess it is a conflict in EF7 because of the fact that every test runs in its own thread and they all kind of using the same DbContext class. Here one of my Tests:

    [Fact]
    public void Index()
    {

        DbContextOptionsBuilder<DatabaseContext> optionsBuilder = new DbContextOptionsBuilder<DatabaseContext>();
        optionsBuilder.UseInMemoryDatabase();
        db = new DatabaseContext(optionsBuilder.Options);
        AdminController controller = new AdminController(db);

        var result = controller.Index() as ViewResult;
        Assert.Equal("Index", result.ViewName);
    }

I remake the dbContext object in every test but it seem not to make any different.

Would be greatful for any input. Thanks :)

Sknecht
  • 984
  • 2
  • 11
  • 31

2 Answers2

3

The problem is, that the memory storage in InMemoryDatabase is registered as Singleton so you actually share the data between DbContexts even you think you don't.

You have to create your DbContexts like this:

public abstract class UnitTestsBase
{
    protected static T GetNewDbContext<T>() where T : DbContext
    {
        var services = new ServiceCollection();

        services
            .AddEntityFramework()
            .AddInMemoryDatabase()
            .AddDbContext<T>(options => options.UseInMemoryDatabase());

        var serviceProvider = services.BuildServiceProvider();

        var dbContext = serviceProvider.GetRequiredService<T>();

        dbContext.Database.EnsureDeleted();

        return dbContext;
    }
}


var newTestDbContext = GetNewDbContext<TestDbContext>()
Skorunka František
  • 5,102
  • 7
  • 44
  • 69
  • How do you do this if you're actually testing an ASP.NET Core application and it's configuring the DbContext in its Startup.ConfigureServices method? – ssmith Oct 26 '16 at 21:52
  • @ssmith: You configure your unit tests to use in memory data context. It does not have anything to do with your App setup. – Skorunka František Oct 28 '16 at 10:49
2

I also was led to beleive that .UseInMemoryDatabase() has no persistence, but that does not seem to be the case (at least with the latest versions)!

As noted in How can I reset an EF7 InMemory provider between unit tests? you want to do a db.Database.EnsureDeleted() BUT I also noticed that this does NOT reset auto increment ids.

Community
  • 1
  • 1
Rick
  • 258
  • 1
  • 16