I'm using XUNIT to test in a dot net core application.
I need to test a service that is internally making an async query on a DbSet in my datacontext.
I've seen here that mocking that DbSet asynchronously is possible.
The problem I'm having is that the IDbAsyncQueryProvider
does not seem to be available in EntityframeworkCore, which I'm using.
Am I incorrect here? Has anyone else got this working?
(Been a long day, hopefully I'm just missing something simple)
EDIT
After asking on GitHub, I got point to this class: https://github.com/aspnet/EntityFramework/blob/dev/src/Microsoft.EntityFrameworkCore/Query/Internal/IAsyncQueryProvider.cs
This is what I've gotten to so far in trying to implement this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Query.Internal;
namespace EFCoreTestQueryProvider
{
internal class TestAsyncQueryProvider<TEntity>: IAsyncQueryProvider
{
private readonly IQueryProvider _inner;
internal TestAsyncQueryProvider(IQueryProvider inner)
{
_inner = inner;
}
IQueryable CreateQuery(Expression expression)
{
return new TestDbAsyncEnumerable<TEntity>(expression);
}
IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
return new TestDbAsyncEnumerable<TElement>(expression);
}
object Execute(Expression expression)
{
return _inner.Execute(expression);
}
TResult Execute<TResult>(Expression expression)
{
return _inner.Execute<TResult>(expression);
}
IAsyncEnumerable<TResult> ExecuteAsync<TResult>(Expression expression)
{
return Task.FromResult(Execute<TResult>(expression)).ToAsyncEnumerable();
}
Task<TResult> IAsyncQueryProvider.ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
{
return Task.FromResult(Execute<TResult>(expression));
}
}
internal class TestDbAsyncEnumerable<T> : EnumerableQuery<T>, System.Collections.Generic.IAsyncEnumerable<T>, IQueryable<T>
{
public TestDbAsyncEnumerable(IEnumerable<T> enumerable)
: base(enumerable)
{ }
public TestDbAsyncEnumerable(Expression expression)
: base(expression)
{ }
public IAsyncEnumerator<T> GetAsyncEnumerator()
{
return new TestDbAsyncEnumerable<T>(this.AsEnumerable()).ToAsyncEnumerable();
}
IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator()
{
return GetAsyncEnumerator();
}
IAsyncEnumerator<T> IAsyncEnumerable<T>.GetEnumerator()
{
throw new NotImplementedException();
}
IQueryProvider IQueryable.Provider
{
get { return new TestAsyncQueryProvider<T>(this); }
}
}
}
I've now tried to implement this and have run into some more issues, specifically around these two methods:
public IAsyncEnumerator<T> GetAsyncEnumerator()
{
return new TestDbAsyncEnumerable<T>(this.AsEnumerable()).ToAsyncEnumerable();
}
IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator()
{
return GetAsyncEnumerator();
}
I'm hoping that somebody could point me in the right direction as to what I'm doing wrong.