I am trying to mock this statement:
IReadOnlyList<Student> students = await _session
.Query<Student>()
.Where(x => x.ClassId == classId)
.ToListAsync(cancellationToken);
My attempt at is:
private Mock<IDocumentSession> _sessionMock = new Mock<IDocumentSession>();
...
_sessionMock
.Setup(x => x
.Query<Students>()
.Where(y => y.ClassId == classId)
.ToListAsync(CancellationToken.None))
.ReturnsAsync(new List<Students));
But i am getting this error:
System.NotSupportedException : Unsupported expression: ... => ....ToListAsync(CancellationToken.None) Extension methods (here: QueryableExtensions.ToListAsync) may not be used in setup / verification expressions.
I looked it up and read the answers I am getting from SOF and other places and understood that basically it's not easily possible to test extension methods.
The answers are old, like 5+ years, some from 2011, since then is there a way to get this to work?
TL;DR: I did not find any working solution to be able to mock
IMartenQueryableThe
IDocumentSessioninterface has the following inheritance chain:Based on the source code the
Querymethod is defined onIQuerySessioninterface like thisThe
IMartenQueryable<T>is indeed anIQueryable<T>.And that could be easily mocked via the MockQueryable.Moq.
I haven't tested the code, maybe you have to cast it to
IMartenQueryable.UPDATE #1
Based on this
QueryableExtensionswe should be able to convertIQueryable<Student>toIMartenQueryable<Student>via theAsoperator.The
Asdefined inside theJasperFx.Core.Reflectionnamespace.I've created to convert
but unfortunately it fails with
InvalidCastException.Tomorrow I'll continue my investigation from here.
UPDATE #2
As it turned out the
As<T>function is just a simple wrapper around type cast... So, it did not help anything.I've also tried to mock directly the
IMartenQueryable<T>and it'sToListAsyncmember method. The problem with this approach is that you need to rewrite your production query to filter elements in memory << kills to whole point of having anIQueryable<T>(or a derived interface).So, I gave up, I don't have any idea, how to do it properly. But as I have seen in the documentation and in the issues we are not the only ones :D