0

Is creating an Interface on DBContext good practice in Entity Framework Core 3.1? Does Microsoft have any documentation on this?

We know that Mocking DBContext in Unit testing is bad practice, however how about creating an Interface over it?

https://learn.microsoft.com/en-us/ef/core/testing/

"However, we never try to mock DbContext or IQueryable. Doing so is difficult, cumbersome, and fragile. Don't do it."

Resources: Why DbContext doesn't implement IDbContext interface?

  • What's your use-case? Are you talking about interfacing the DbContext itself or the entities? – Xerillio Feb 02 '21 at 18:09
  • Well instead of extracting an interface out of the DbContext I'd recommend to use the repository pattern and extract interfaces from you repository / repositories and your UnitOfWork – FFranz Feb 02 '21 at 18:29
  • hi @Xerillio interfacing the DbContext itself –  Feb 02 '21 at 20:10

1 Answers1

0

If your objective is to facilitate unit testing code that interacts with the DbContext then I would recommend looking at implementing the Repository pattern alongside a Unit of Work to manage the DbContext lifetime scope and commits. I have outlined effective ways to implement flexible, and easily test-able repository classes in various answers, but this one probably sums it up best: (How to set multiple services from Entity Framework Core on Repository Pattern?)

I recommend avoiding generic repository implementations and embracing the power of EF's IQueryable support to build an extremely simple layer to mock that can provide efficient and flexible querying.

The last detail is if you do want to support async querying through the repository and want to unit test those, an invaluable tip to support this can be found here: (Unit-testing .ToListAsync() using an in-memory)

Steve Py
  • 26,149
  • 3
  • 25
  • 43
  • this is helpful, how about original question, for apply interface on database or not? –  Feb 02 '21 at 22:09
  • For what purpose? You stated "We know that Mocking DBContext in Unit testing is bad practice, however how about creating an Interface over it?" so if you want to unit test around it then use a Repository pattern. Putting an interface over it doesn't accomplish anything because you're still in a position where you either have to Mock complex structures like `DbSet`, or exposing `IQueryable`, or worse, `IEnumerable` in place of *every* DbSet. (Where a repository only exposes what the consumer under test is expected to need) – Steve Py Feb 02 '21 at 22:28
  • 1
    well, I am trying to understand why my architect is trying to create interface on dbContext, I already told him mocking dbContext is not recommended practice from Microsoft article, so what other reason can there be? Need to prepare notes before meeting –  Feb 02 '21 at 22:44
  • My guess would be "abstraction for the sake of abstraction". :) A good response would be: https://stackoverflow.com/questions/50174203/abstracting-ef-core-2-dbcontext There will always be developers that want to try and "hide" the fact that they are using an Entity Framework DbContext, or go through the effort of trying to mock it. This more often than not ends in a spectacularly complex mess and/or a performance nightmare. – Steve Py Feb 02 '21 at 23:12
  • maybe you can answer this too? thanks https://stackoverflow.com/questions/66022434/entity-framework-core-enable-duplicate-primary-keys-in-inmemorydb-testing –  Feb 03 '21 at 07:10
  • DbContext already implements/is a Unit of Work – Tomas Voracek Oct 27 '22 at 16:00
  • Yes, though if you want something easier to mock than a DbContext then there are explicit unit of work patterns that can encapsulate the DbContext to make it easier to test around. They also afford you more control over the scope of the UoW so no special exceptions to the design pattern where I want things like parallel operations. – Steve Py Oct 27 '22 at 21:16