Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

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?

+2
−0

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.

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

Post
+2
−0

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.

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

1 comment thread

General comments (4 comments)
General comments
Alexei‭ wrote almost 4 years ago

That's an interesting perspective as I failed to realize that indeed the tests have to know something about the infrastructure (the DbSets actually). However, some aspects of your answer are not clear. In my case unit tests require the class to be tested + mocking. The alternative requires the class to be tested + the database provider to be set up (with mock data). The tests are covering both functionality and the persistence.

Alexei‭ wrote almost 4 years ago

Also, it is not clear why I need more classes. Indeed I might need more code in the tests since each test class defines its own mocks as opposed to the in-memory provider which might have a single place to define all mock data. The setup is actually simpler because it consists of defining mocks for DbSets as opposed to defining and using the in-memory provider.

Goyo‭ wrote almost 4 years ago

Sorry, I don't know why I got the wrong impression that you were writing mock classes. But anyway you have to code the mocks' behavior. More code, that is the point. I am not really qualified to compare the complexity of the setup for each approach but I don't expect it to make much of a difference. Of course I might be wrong and then that would make a good case for the mocks.

Goyo‭ wrote almost 4 years ago

"The tests are covering both functionality and the persistence." Be careful. You are testing the functionality. Persistence or mocks can be involved as well as language constructs. But you are testing neither the persistency, the mocks nor the language, you just trust them.