I'm mocking a DbSet from Entify Framework. I want to use its extension method ToListAsync. This is how I do it and below a result of my attempt (regular ToList works):
IQueryable<DbUser> userData = MockedData.Instance.Users; // this is just a property to get custom IQueryable set of data for testing
var dbSetMock = new Mock<DbSet<DbUser>>();
dbSetMock.As<IQueryable<DbUser>>().Setup(m => m.Provider).Returns(userData.Provider);
dbSetMock.As<IQueryable<DbUser>>().Setup(m => m.Expression).Returns(userData.Expression);
dbSetMock.As<IQueryable<DbUser>>().Setup(m => m.ElementType).Returns(userData.ElementType);
dbSetMock.As<IQueryable<DbUser>>().Setup(m => m.GetEnumerator()).Returns(userData.GetEnumerator());
/*
I've put it here so you can see how I tried to approach my problem
dbSetMock.Setup(x => x.ToListAsync())
.Returns(Task.FromResult(userData.ToList()));
*/
var testAsync = dbSetMock.Object.ToListAsync();
var testRegular = dbSetMock.Object.ToList();
Results:
The variable testRegular has value as expected. But the variable testAsync has value like this:

When I uncomment the part where I try to setup ToListAsync to return anything I get an exception like this:
{"Expression references a method that does not belong to the mocked object: x => x.ToListAsync<DbUser>()"}
I'd appreciate any suggestions. Should I switch to Fakes maybe? is such functionality supported there?
I found and used this code with success:
dbSetMock.As<IDbAsyncEnumerable<DbUser>>()
.Setup(m => m.GetAsyncEnumerator())
.Returns(new AsyncEnumerator<DbUser>(userData.GetEnumerator()));
with the following support class (note use of C#6 shorthand features):
class AsyncEnumerator<T> : IDbAsyncEnumerator<T>
{
private readonly IEnumerator<T> _inner;
public AsyncEnumerator(IEnumerator<T> inner)
{
_inner = inner;
}
public void Dispose() => _inner.Dispose();
public Task<bool> MoveNextAsync(CancellationToken cancellationToken) => Task.FromResult(_inner.MoveNext());
public T Current => _inner.Current;
object IDbAsyncEnumerator.Current => Current;
}
The root cause of the error is that Moq cannot mock static methods, at least for now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With