RE: IQueryable mock throws on ToListAsync()
See original GitHub issueThis issue is related to #32 but there was no resolution given there so I am opening a new issue.
When mocking an IQueryable, I am getting the exception
System.InvalidOperationException : The source IQueryable doesn't implement IAsyncEnumerable<Event>. Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations.
My code is structured as follows:
// Method Under Test
public async Task<List<Event>> GetEvents(FilterOptions filterOptions)
{
var queryable = GetEventsQueryable();
queryable = FilterByDate(queryable, filterOptions);
// queryable = FilterByLocation(), FilterBy...(), etc
var events = await queryable
.ToListAsync()
.ConfigureAwait(false);
return events;
}
public IQueryable<Event> GetEventQueryable()
{
try
{
return MyDbContext
.EventData
.AsQueryable();
}
catch
{
...
}
}
public IQueryable<Event> FilterByDate(
IQueryable<Event> queryable,
FilterOptions options)
{
if (options.StartDate != null)
{
queryable = queryable.Where(e => e.EventDate >= options.StartDate);
}
if (options.EndDate != null)
{
queryable = queryable = queryable.Where(e => e.EventDate <= options.EndDate);
}
return queryable;
}
// Test
private List<Event> Events
{
get
{
new List<Event>
{
...
};
}
}
[Fact]
public void GetEvents_DefaultFilterOptions_ReturnsAllEvents()
{
// Arrange
var mockQueryable = Events.AsQueryable().BuildMock();
var expectedEvents = new List<Event>
{
...
};
...
mockCaller
.Setup(m => m.GetEventsQueryable())
.Returns(mockQueryable);
mockCaller
.Setup(m => m.FilterByDate(It.IsAny<IQueryable<Event>>(), It.IsAny<FilterOptions>()))
.Returns(mockQueryable);
var eventManager = new EventManager();
var filterOptions = new EventFilterOptions();
// Act
var actualEvents = eventManager.GetEvents(filterOptions);
// Assert
Assert.Equal(expectedEvents, actualEvents);
}
When the test gets to the events = await queryable.ToListAsync()
line it throws the System.InvalidOperationException.
I am not sure what is going wrong or how to fix the issue. I started looking into using the TestAsyncEnumerableEfCore<Event> class and trying to return this instead of the mocked queryable, but the issue still persisted.
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (2 by maintainers)
Top Results From Across the Web
IQueryable mock throws on ToListAsync() · Issue #32
ToListAsync() on my mock queryable still throws: System.InvalidOperationException : The source IQueryable doesn't implement ...
Read more >Mocking ToListAsync on a Mock<DbSet<T>> using Moq
I've got a method that converts a List to a DbSet which I use when mocking the data my database context should return....
Read more >Supporting async LInQ evaluation on IQueryable mocks
The problem is that if you wrap your list into an IQueryable<T> then you can call ToListAsync() on it — but it gives...
Read more >Mocking IQueryable Extensions with Moq - The Seeley Coder
Mocking IQueryable extensions such as Where or FirstOrDefault on an IQueryable is difficult. Come learn one workaround I found.
Read more >Query.ToListAsync() throws exception
I rearranged the Where and Take clauses, but it made no difference. My failing test which gives the exception: [Test]. public void Should_return_async_balance()....
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Thank you! I think I accidentally copied from an older commit, which is why the
BuildMock()
call was missing. You are correct, the real issue was the missing nullable DateTimes in the mock. Can’t believe it was so simple. Thanks for your help.@sstream17 if you change your test like this it will work.
Main issue was because
FilterByDate
does not return mock object because it was wrongly initialized