Jimmy Boy
Jimmy Boy

Reputation: 129

Xunit new in memory database DBContext Class has live data

I am trying to unit test with the EF Core in-memory database like so:

namespace ContosoTests
{
    public class TrendServiceTests
    {
       private static Microsoft.EntityFrameworkCore.DbContextOptions<TestContext> options = new 
       Microsoft.EntityFrameworkCore.DbContextOptionsBuilder<TestContext>()
                       .UseInMemoryDatabase(Guid.NewGuid().ToString())
                       .Options;

       private static TestContext _context = new TestContext(options);

       private readonly TrendService trendService = new TrendService(_context);

        private void SeedInMemoryDb()
        {
            if (!_context.TrendHistories.Any())
            {
                _context.TrendHistories.Add(new TrendHistory { IsActive = true, Quarter = E_Quarter.Q1, 
                TrendYear = 2020 });
            }

            if (!_context.Controls.Any())
            {
                _context.Controls.Add(new Control { IsActive = true});
                _context.Controls.Add(new Control { IsActive = true});
                _context.Controls.Add(new Control { IsActive = false});
            }

            _context.SaveChanges();
        }
}

My TestContext inherits from my live context class to avoid the error:
Services for database providers 'Microsoft.EntityFrameworkCore.InMemory', 'Microsoft.EntityFrameworkCore.SqlServer' have been registered in the service provider. Only a single database provider can be registered in a service provider

So my TestContext just looks like:

public class TestContext : ContosoContext
    {
        public TestContext(DbContextOptions<TestContext> options)
        {
            
        }

        public TestContext()
        {

        }
    }

When I use the new instance of TestContext (_context) in my test class, all the live data for ContosoContext is there. I was expecting it to be a new instance of the context class with no data so that I could test my DAL code with controlled data. But this is not the case.

I am fairly new to unit testing so any help is much appreciated.

Edit:
Here are the relevant parts of my contoso context class

    public class ContosoContext: IdentityDbContext<ContosoApplicationUser>
    {
        public ContosoContext(DbContextOptions<ContosoContext> options) : base 
        (options)
        {

        }

        public ContosoContext()
        {

        }

        //all my DBSets here

        protected override void OnConfiguring(DbContextOptionsBuilder 
        optionsBuilder)
        {

            optionsBuilder.UseSqlServer("MyConnectionString");

        }
    }

So the issue is that my onconfiguring method handles the connection string directly??

Upvotes: 2

Views: 2268

Answers (1)

Mohsen Esmailpour
Mohsen Esmailpour

Reputation: 11554

To fix the error you need to remove optionsBuilder.UseSqlServer("MyConnectionString"); in OnConfiguring method to avoid registering multiple database providers, change it to this:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if(!optionsBuilder.IsConfigured)
        optionsBuilder.UseSqlServer("MyConnectionString");
}

Upvotes: 3

Related Questions