New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async MOQ testing with EntityFramework Core #6631

Closed
chrispaynter opened this Issue Sep 28, 2016 · 9 comments

Comments

Projects
None yet
8 participants
@chrispaynter

chrispaynter commented Sep 28, 2016

I'm using xunit to test some services in a .NET Core application. The services are using EF Core and I will need to be able to use Moq to mock up the DbSets, using async queries.

I've tried this guide where it suggest creating a custom IDbAsyncQueryProvider to enable async mocks - https://msdn.microsoft.com/en-us/data/dn314429#async

The problem I'm having is that the IDbAsyncQueryProvider does not seem to be available in EntityframeworkCore.

Is there an alternative I can use for this purpose?

@divega

This comment has been minimized.

Show comment
Hide comment
@divega

divega Sep 28, 2016

Member

@chrispaynter this may help: https://github.com/aspnet/EntityFramework/blob/dev/src/Microsoft.EntityFrameworkCore/Query/Internal/IAsyncQueryProvider.cs

Note that it is in an internal namespace meaning that if you are going to reference it directly in your tests you have to be ok with us breaking it in the future, even in a minor release.

Let us know if you get blocked with anything else.

A more general approach that may help is to use the in-memory database that comes with EF Core or an in-memory SQLite database. Of course this helps more if you were using Moq to create fake DbSets.

Member

divega commented Sep 28, 2016

@chrispaynter this may help: https://github.com/aspnet/EntityFramework/blob/dev/src/Microsoft.EntityFrameworkCore/Query/Internal/IAsyncQueryProvider.cs

Note that it is in an internal namespace meaning that if you are going to reference it directly in your tests you have to be ok with us breaking it in the future, even in a minor release.

Let us know if you get blocked with anything else.

A more general approach that may help is to use the in-memory database that comes with EF Core or an in-memory SQLite database. Of course this helps more if you were using Moq to create fake DbSets.

@rowanmiller

This comment has been minimized.

Show comment
Hide comment
@rowanmiller

rowanmiller Oct 4, 2016

Member

We would also generally discourage trying to mock EF - it typically ends up being pretty complex to try and replicate all the behavior of EF in your mocks. We would suggest either using an in-memory database with EF (either our InMemory provider, or SQLite running in in-memory mode) or introducing a repository abstraction and mocking that.

Member

rowanmiller commented Oct 4, 2016

We would also generally discourage trying to mock EF - it typically ends up being pretty complex to try and replicate all the behavior of EF in your mocks. We would suggest either using an in-memory database with EF (either our InMemory provider, or SQLite running in in-memory mode) or introducing a repository abstraction and mocking that.

@rossvegas

This comment has been minimized.

Show comment
Hide comment
@rossvegas

rossvegas Mar 17, 2017

Hi @rowanmiller, in your last comment you discouraged trying to mock EF.

I have just been doing a Pluralsight course by @julielerman from Sept 2016, she says that because a DBContext is an implementation of the repository pattern itself you don't need to implement the repository pattern again through your own classes creating what could be an unnecessary abstraction. She mentions the following MSDN post on how to Mock EF. Part of it shows creating a test TestDBAsyncQueryProvider which implements IDbAsyncQueryProvider. It was updated October 23 2016.

https://msdn.microsoft.com/en-us/library/dn314429(v=vs.113).aspx

It seems as though people are trying to use this method with dotnet core recently as well.

See accepted answer of this stack overflow of an example of how to mock the new IAsyncQueryProvider interface
http://stackoverflow.com/questions/40476233/how-to-mock-an-async-repository-with-entity-framework-core.

So My Question is does the EF Core team think Mocking EF is a good or bad idea, and what is the support for it?

rossvegas commented Mar 17, 2017

Hi @rowanmiller, in your last comment you discouraged trying to mock EF.

I have just been doing a Pluralsight course by @julielerman from Sept 2016, she says that because a DBContext is an implementation of the repository pattern itself you don't need to implement the repository pattern again through your own classes creating what could be an unnecessary abstraction. She mentions the following MSDN post on how to Mock EF. Part of it shows creating a test TestDBAsyncQueryProvider which implements IDbAsyncQueryProvider. It was updated October 23 2016.

https://msdn.microsoft.com/en-us/library/dn314429(v=vs.113).aspx

It seems as though people are trying to use this method with dotnet core recently as well.

See accepted answer of this stack overflow of an example of how to mock the new IAsyncQueryProvider interface
http://stackoverflow.com/questions/40476233/how-to-mock-an-async-repository-with-entity-framework-core.

So My Question is does the EF Core team think Mocking EF is a good or bad idea, and what is the support for it?

@ajcvickers

This comment has been minimized.

Show comment
Hide comment
@ajcvickers

ajcvickers Mar 17, 2017

Member

@rossvegas If you are trying to mock your data layer, then using a repository or similar is probably a better way to go than attempting to mock EF directly. However, there are many other valid ways to develop/test that don't involve mocking the data layer. In such cases creating a repository can be overkill because it isn't providing any value over what the context already has.

Member

ajcvickers commented Mar 17, 2017

@rossvegas If you are trying to mock your data layer, then using a repository or similar is probably a better way to go than attempting to mock EF directly. However, there are many other valid ways to develop/test that don't involve mocking the data layer. In such cases creating a repository can be overkill because it isn't providing any value over what the context already has.

@julielerman

This comment has been minimized.

Show comment
Hide comment
@julielerman

julielerman Mar 17, 2017

Hey @rossvegas , I would like to clarify something about what you say you heard in my course. I have an entire module called "Understanding EF Encapsulation and the Great Repository Debates" where I pointed out that one argument is that the dbcontext is a repo so you don't need to abstract it but that there are times when implementing a repository pattern is perfectly reasonable. And that there are times when it makes more sense to create classes that encapsulate your data access needs that don't happen to follow the repository pattern. The last is my preference. But I worked hard to give a fair and balanced perspective on the topic. I demonstrated testing EF directly, testing the repo pattern class and testing a class that encapsulated data calls. If you you missed something about that discussion -- that's fine -- but I just wanted to be careful about a misconstrued message being relayed as "julie said". ;)

julielerman commented Mar 17, 2017

Hey @rossvegas , I would like to clarify something about what you say you heard in my course. I have an entire module called "Understanding EF Encapsulation and the Great Repository Debates" where I pointed out that one argument is that the dbcontext is a repo so you don't need to abstract it but that there are times when implementing a repository pattern is perfectly reasonable. And that there are times when it makes more sense to create classes that encapsulate your data access needs that don't happen to follow the repository pattern. The last is my preference. But I worked hard to give a fair and balanced perspective on the topic. I demonstrated testing EF directly, testing the repo pattern class and testing a class that encapsulated data calls. If you you missed something about that discussion -- that's fine -- but I just wanted to be careful about a misconstrued message being relayed as "julie said". ;)

@rossvegas

This comment has been minimized.

Show comment
Hide comment
@rossvegas

rossvegas Mar 17, 2017

Thanks @ajcvickers and @julielerman I appreciate there are debates surrounding the use of repositories and different strategies for them. Also @julielerman I am a big fan I have been following your guidance for years.

My question is really regarding support by the EF Core for mocking. The MSDN link I posted indicated that Microsoft supported and demonstrated mocking for EF6. Is this not the case any more with Core? The reason i ask and this is the only indicator I can find on the whole internet is that Rowan said "We would also generally discourage trying to mock EF".

I just wanted to check if this discussion had been had by the team and if there was any official word on the subject and if Rowans comment was his own opinion or represented the teams outlook on the matter.

rossvegas commented Mar 17, 2017

Thanks @ajcvickers and @julielerman I appreciate there are debates surrounding the use of repositories and different strategies for them. Also @julielerman I am a big fan I have been following your guidance for years.

My question is really regarding support by the EF Core for mocking. The MSDN link I posted indicated that Microsoft supported and demonstrated mocking for EF6. Is this not the case any more with Core? The reason i ask and this is the only indicator I can find on the whole internet is that Rowan said "We would also generally discourage trying to mock EF".

I just wanted to check if this discussion had been had by the team and if there was any official word on the subject and if Rowans comment was his own opinion or represented the teams outlook on the matter.

@ajcvickers

This comment has been minimized.

Show comment
Hide comment
@ajcvickers

ajcvickers Mar 18, 2017

Member

@rossvegas I'm not sure what makes something "official" 😸, but I think there is general agreement across the team with what Rowan said.

Member

ajcvickers commented Mar 18, 2017

@rossvegas I'm not sure what makes something "official" 😸, but I think there is general agreement across the team with what Rowan said.

@pgorbas

This comment has been minimized.

Show comment
Hide comment
@smitpatel

This comment has been minimized.

Show comment
Hide comment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment