Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Comments on What are the cons of directly mocking Entity Framework DbSets instead of working with an in-memory database when unit testing the application?
Parent
What are the cons of directly mocking Entity Framework DbSets instead of working with an in-memory database when unit testing the application?
I have recently contributed to a Clean Code project and had a discussion about how to implement unit tests.
The project author argues for using an in-memory database (which easily replaces the real one) instead of mocking the DbSets and now I am doubting my own approach.
The in-memory database approach for unit testing means that in order to unit test, the project setup is changed to use an in-memory provider instead of a real one (e.g. SQL Server provider). All services dependencies remain unchanged (no need for mocking here).
The DbSets mocking means that for each service I need to explicitly mock the dependency (DbSet is mocked using a library to a static list).
I tend to favor my approach because:
- sounds purely unit testing: mock the inputs, not an indirect input as the database
- no need for a special set up for testing (i.e. unit tests do not have to know anything about the infrastructure)
I am wondering what cons the DbSet mocking might have.
Post
The problem is that you have to write code for the test doubles and its behavior. In the author's eyes that is just unnecessary complexity because the required behavior is already provided by the framework.
If you checked Jason's talk (do it now if you didn't, really) you will find that in his simplified approach (which he seems to be using here) EF is used the same way as if it was a part of the language instead of an external dependency. That's why the advantages you mention are of little value to him:
sounds purely unit testing: mock the inputs, not an indirect input as the database
It has been already decided that depending on EF everywhere is OK. In that context, mocking EF interfaces makes as much sense as mocking built-in collections.
no need for a special set up for testing (i.e. unit tests do not have to know anything about the infrastructure)
But the tests have to know about the infrastructure anyway because there are infrastructure interfaces involved. Pretending that the tests are infrastructure agnostic won't fly. And you always need some set up. Setting up the framework feels more straightforward and convenient than setting up mocks in this context. If setting up the framework required a disproportionate amount of work that would be a good argument for your approach, but that is probably not the case (I speak little C# and zero EF so I can't really tell).
The convention that EF is to be used as if it were part of the language is critical here. It is what allows objects not in the outermost layers to depend on EF and still being clean architecture. If EF were considered an external dependency this would be against the dependency rule.
By mocking EF interfaces you are treating them like external dependencies, thus subverting the convention. Your tests are screaming "Not clean!" and the next thing you would want to do is restoring the dependency rule by putting your own thin abstractions between the framework and the rest of the code. But that is obviously not how Jason sees it.
In summary, your attempt to decouple the tests from the framework failed (because the framework interfaces are still there) and doesn't fit the overall architecture and design. It is natural that the framework pervades the tests when it pervades the code base too.
0 comment threads