How to unit test what is setup in overridden OnModelCreating

in-memory testing
c# in-memory database for unit testing
mock dbcontextoptions
unit test dbcontext
useinmemorydatabase
ef core test connection
cannot open database efproviders inmemory requested by the login
in-memory sql server for testing

I'm using Entity Framework 6 and in my context I have overridden OnModelCreating method:

protected override void OnModelCreating(DbModelBuilder modelBuilder)

Inside the method, I set up the database configuration. I would like to test what is set up. For instance, I have the following code:

modelBuilder.HasDefaultSchema("public");

I would like to have a unit test which checks that HasDefaultSchema with parameter value "public" is called.

Or like in the following example I would like to test that HasMany and WithMany methods of entity UserGroup are called:

 modelBuilder.Entity<UserGroup>()
             .HasMany<User>(g => g.Users)
             .WithMany(u => u.Groups)
             .Map(ug =>
                  {
                     ug.MapLeftKey("GroupId");
                     ug.MapRightKey("UserId");
                     ug.ToTable("UserGroupMembers");
                  });

Please advise. Thanks


I came up with the following solution in .Net Core. In my case I have a base DbContext where I interpret a custom DataAnnotation in order to tell EF to ignore certain properties on my model classes (the functionality I wanted to test).

I could not simply use NotMapped because it caused OData to not be able to see NotMapped properties when specified in the $select, so I needed an alternative way to tell EF to ignore, but not impact OData.

In my case I also created a TestDbContext which inherited from my standard test ModelDbContext class (which in turn inherits from my library DbContextBase class which does the EF Ignore work), but I simply set a property to the provided ModelBuilder so that I could interrogate it during my tests.

    public class TestDbContext : ModelDbContext
    {
      public ModelBuilder ModelBuilder { get; private set; }

      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
        base.OnModelCreating(modelBuilder);
        this.ModelBuilder = modelBuilder;
      }
    }

Then I could test it using the following code:

Note: I had to use reflection to extract the EF internal classes required to determine if indeed the field was set to Ignored. This is normally bad practice, but I could not figure out another way of determining whether EF was ignoring these properties.

    [Fact]
    public void OnModelCreatingTest()
    {
      // Arrange
      DbContextOptionsBuilder<ModelDbContext> builder = new DbContextOptionsBuilder<ModelDbContext>().UseInMemoryDatabase(Guid.NewGuid().ToString());
      var context = new TestDbContext(builder.Options);

      // Act
      // hit the entities to force the model to build
      var testEntity = context.ExampleEntities.FirstOrDefault();
      // use reflection to dig into EF internals
      var builderProperty = typeof(EntityTypeBuilder).GetProperty(
          "Builder",
          System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

      // Assert
      // validate that the extra ExampleEntity fields are ignored in EF (based on their data annotation)
      context.ModelBuilder.Entity(
        typeof(ExampleEntity),
        b =>
        {
          InternalEntityTypeBuilder baseBuilder = (InternalEntityTypeBuilder)builderProperty.GetValue(b);
          Assert.True(baseBuilder.IsIgnored("Property1", ConfigurationSource.Convention));
          Assert.True(baseBuilder.IsIgnored("Property2", ConfigurationSource.Convention));
        });
    }

How do I unit test implementations of IEntityTypeConfiguration , OnModelCreating. For example: protected override void OnModelC gforceg changed the title How do I run a migration in a unit test? FilePath = filePath; } public void Configure(EntityTypeBuilder<TEntity> builder)  The default implementation of this method does nothing, but it can be overridden in a derived class such that the model can be further configured before it is locked down. protected virtual void OnModelCreating (System.Data.Entity.DbModelBuilder modelBuilder);


You could create a stub for you DbContext that explicit call OnModelCreating and check the state of the DbModelBuilder

public class TestableMyDbContext : MyDbContext
  {
    public void TestModelCreation(DbModelBuilder model)
    {
        OnModelCreating(model);
        // check your model an throw an exception if invalid
    }
  }

And in the TestMethod you catch the exception

[TestMethod]
public void Should_Initialize_Context()
{
  try
  {
    var context = new TestableMyDbContext();
  context.TestCallback(new DbModelBuilder());
  }
  catch (Exception ex)
  {
    Assert.Fail(ex.Message);
  }     
}

How to unit test what is setup in overridden OnModelCreating, protected override void OnModelCreating(DbModelBuilder modelBuilder). Inside the method, I set up the database configuration. I would like to test what is set  These invariants must be maintained if this method is overridden for anything other than creating test doubles for unit testing. See the DbSet class for more details. Set<TEntity>()


To build on vappolinario's answer, I used a Mock<DbModelBuilder> and passed that into the TestableDbContext, and then verified that the mock was called correctly.

I am using Moq and xUnit in my example

[Fact]
public void MyContext_HasCorrectDefaultSchema()
{
   var mockModel = new Mock<DbModelBuilder>();
   var context = new TestableMyContext();

   context.TestOnModelCreation(mockModel.Object);

   mockModel.Verify(m => m.HasDefaultSchema("public"), Times.Once());
}

Unit Testing EF Core, Unit Testing EF Core – How to Invoke the Contents of protected override void OnModelCreating(ModelBuilder modelBuilder). {. modelBuilder  Use fluent API to configure a model. You can override the OnModelCreating method in your derived context and use the ModelBuilder API to configure your model. This is the most powerful method of configuration and allows configuration to be specified without modifying your entity classes.


I didn't get the stub technique to work, but this did:

[TestMethod]
public void Should_Initialize_Context()
{
    try
    {
        var context = new MyDbContextContext("blah");
        context.Database.Initialize(false);

    }
    catch (Exception ex)
    {
        Assert.Fail(ex.Message);
    }
}

Mocking Entity Framework Core DBContext for unit testing, We have unit tests for the repository layer where the DbContext is used. override void OnModelCreating(ModelBuilder modelBuilder)  0 How to unit test what is setup in overridden OnModelCreating Jan 7 '16. Badges (29) Gold. 1. Rarest. Famous Question. Oct 21 '12. Silver. 8. Rarest. Civic Duty. Apr


Unit testing in ASP.NET Core with EF Sqlite in-memory and XUnit , A simple example how to do unit testing in ASP. protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder. Select the Add unit tests option. The unit test project is automatically named StoreApp.Tests. You can keep this name. After creating the application, you will see it contains two projects - StoreApp and StoreApp.Tests. Create the model class. In your StoreApp project, add a class file to the Models folder named Product.cs. Replace the contents of the file with the following code.


Entity Framework Core Cookbook, OnModelCreating(modelBuilder); } protected override void OnConfiguring( Now, let's add a unit test in the UnitTests project, in a file called ShadowTests. using ctx = new BlogContext( Configuration["Data:Blog:ConnectionString"])) { //​Act  26.3. unittest — Unit testing framework¶ (If you are already familiar with the basic concepts of testing, you might want to skip to the list of assert methods.). The unittest unit testing framework was originally inspired by JUnit and has a similar flavor as major unit testing frameworks in other languages.


How to unit test EF core 3 view with no key in-memory?, protected override void OnModelCreating(ModelBuilder (by convention) you only use during testing, and you configure the model to ignore  See Testing code that uses EF Core for general information on testing with the EF in-memory database. See Sample showing how to test applications that use EF Core for a sample using the EF in-memory database. See The EF in-memory database provider for general information about the EF in-memory database. Related Articles