Moq.EntityFrameworkCore
Moq.EntityFrameworkCore copied to clipboard
Public ConfigureMock or IQueryableExtension
Hi. Thanks for a very useful library. I have a small feature request:
I have a few cases where I have a DbContext with an IQueryable<TEntity>
which points to a DbSet<TEntity>
.
The IQueryable<TEntity>
is typically part of an interface I want to mock, but I want to use EF Core "Async" stuff in the actual implmentation.
Yes I know the implementation will break if ever the IQeuryable is replaced with something that is NOT a DbSet....but thats another story.
When testing I would like to do something like the following:
var entities = new List<Entity> { existing };
this.mockContext.Setup(x => x.QueryEntities).ReturnsDbSet(entities);
But that I cannot as ReturnsDbSet is defined on DbSet<T>.
So what I end up doing is to create my own extension method, or in somecases copy/paste the ConfigureMocks method and just call that explictly like so:
[Fact]
public void TestStuff()
{
var existing = new List<Entity>{ /*here be dragons. */ };
var entities = new Mock<DbSet<Entity>>();
ConfigureMock(entities , existing);
this.mockContext.Setup(x => x.QueryEntities).Returns(entities.Object);
}
private static void ConfigureMock<TEntity>(Mock dbSetMock, IEnumerable<TEntity> entities) where TEntity : class
{
IQueryable<TEntity> entitiesAsQueryable = entities.AsQueryable();
dbSetMock.As<IAsyncEnumerable<TEntity>>().Setup((IAsyncEnumerable<TEntity> m) => m.GetAsyncEnumerator(CancellationToken.None)).Returns(new InMemoryDbAsyncEnumerator<TEntity>(entitiesAsQueryable.GetEnumerator()));
dbSetMock.As<IQueryable<TEntity>>().Setup((IQueryable<TEntity> m) => m.Provider).Returns(new InMemoryAsyncQueryProvider<TEntity>(entitiesAsQueryable.Provider));
dbSetMock.As<IQueryable<TEntity>>().Setup((IQueryable<TEntity> m) => m.Expression).Returns(entitiesAsQueryable.Expression);
dbSetMock.As<IQueryable<TEntity>>().Setup((IQueryable<TEntity> m) => m.ElementType).Returns(entitiesAsQueryable.ElementType);
dbSetMock.As<IQueryable<TEntity>>().Setup((IQueryable<TEntity> m) => m.GetEnumerator()).Returns(() => entitiesAsQueryable.GetEnumerator());
}
It works - but its annoying to repeat all the time.