7

In Entity Framework you can configure the relationship between your entities by either using data annotations inside the actual class entity:

public class Entity
{
    [Key, Column(Order = 0)]
    public Guid PartOfPrimaryKey { get; set; }

    [Key, Column(Order = 1)]
    public Guid AlsoPartOfPrimaryKey { get; set; }
}

or by using the fluent API configuration

    modelBuilder.Entity<Entity>()
                .HasKey(k => new { k.PartOfPrimaryKey, k.AlsoPartOfPrimaryKey });

Give that you've used the fluent API configruation approach, how do you make sure the configuration is executed while mocking (using Moq) the DbContext for unit testing?

When i mock the DbContext the method OnModelCreating is not being executed.

Here is an explanation of how to test your application using a mocking framwork, but it doesn't explain how they take care of the problem with "configuring" the entities. Other posts I have found doesn't address this issue either. I guess there's something simple i'm missing.

Sidenote: I'm also aware of that it might not be a good idea at all to unit test your DbContext because you will use LINQ to Objects in your tests and LINQ to entites in production. However, I still think there is an answer to my question.

Update: If I use the data annotations instead, it works fine.

Community
  • 1
  • 1
Jim Aho
  • 9,932
  • 15
  • 56
  • 87

2 Answers2

2

I'd never mock an ORM. I prefer to create intermediate classes that implement an interface (for example a repository) and mock that interface. However, let's see what I can do for you:

A good way to mock a DbContext for unit testing that will work with Fluent API, annotations, and so on, is to use an in-memory DB. Even if it's a DB is still fast enough for unit testing. It also allows you to mock an insert-read or insert-update-read sequence in a transparent way.

Please, see this Q&A (and don't take the accepted answer as the best one, because it isn't):

Is there an in-memory provider for Entity Framework?

Community
  • 1
  • 1
JotaBe
  • 38,030
  • 8
  • 98
  • 117
  • I think you're correct, and what I did wrong in the first place was to mock our DbContext. Although it's not a complete answer to the question, I mark it as 'accepted' because of your first statement. The more correct way is to mock the interface instead, and in the case where you need to execute your modelbuilder to enforce validation, using an in-memory database might be the correct option. – Jim Aho Nov 04 '14 at 15:35
  • What is the actual answer though as to why OnModelCreating is not getting called? – sovemp Jan 10 '17 at 19:43
  • @sovemp Because it's a mock. The mock is not the `DbContext` class, but a mock of it, so it doesn't have the `Dbcontext` functionality, including the invocation oft he fluent API configuration. Even without seeing the `DbContext` mock implementation, I'm sure that it uses the entity classes, as they're, so their data annotaiton attributes are available. That's why data annotations work fine, and fluent API doesn't. – JotaBe Jan 11 '17 at 11:57
0

At first I also used Moq to test my code against the database. But after a while I had issues and nothing worked as expected.

Now I am using this one here: http://effort.codeplex.com/

Take a look at it. For me it's much easier to test my code. And it's much faster to write tests for it.

0lli.rocks
  • 1,027
  • 1
  • 18
  • 31