Reputation: 13387
I am trying to test a bit of code I have:
public async Task<Sortation> SaveAsync(Sortation sortation)
{
if (sortation.Id == 0)
{
var sortations = await ListAsync(sortation.CategoryId);
sortation.Order = sortations.Count;
_sortationService.Create(sortation);
}
else
{
_sortationService.Update(sortation);
}
await _sortationService.SaveChangesAsync();
return sortation;
}
The ListAsync method is causing me an issue. I set up my test like this:
[Test]
public async Task ShouldHaveOrderOfZero()
{
// Assemble
const string categoryId = "cameras";
var services = SortationContext.GivenServices();
var sortationProvider = services.WhenGetSortationProvider();
var sortations = new List<Sortation>();
var sortation = new Sortation { CategoryId = categoryId };
services.MockSortationService.Setup(x => x.List()).Returns(sortations.AsQueryable);
// Act
await sortationProvider.SaveAsync(sortation);
// Assert
sortation.Order.Should().Be(0);
}
And when I run this, I get this error:
Message: System.InvalidOperationException : The source IQueryable doesn't implement IDbAsyncEnumerable. Only sources that implement IDbAsyncEnumerable can be used for Entity Framework asynchronous operations.
According to this: Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations I need to add EF to my UnitTest project, which I did. But the error still persists.
The ListAsync method looks like this:
public async Task<List<Sortation>> ListAsync(string categoryId, params string[] includes) =>
await _sortationService.List(includes).Where(m => m.CategoryId.Equals(categoryId)).ToListAsync();
Does anyone know how I can stop this error from happening?
Upvotes: 3
Views: 6779
Reputation: 221
In my case the exception was caused by using the wrong ToListAsync extension.
It came from:
using System.Data.Entity; instead of
using Microsoft.EntityFrameworkCore; Changing the namespace fixed the error.
Upvotes: 22
Reputation: 1720
Don't know if question is still actual, but still. I agree with Mark's comment, however here is an example, that works for me. I added some reasonable stub implementation for mentioned class, because there are not enouch details in question. I can be wrong in my assumptions:
[Test]
public async Task ShouldHaveOrderOfZero()
{
// Assemble
const string categoryId = "cameras";
var services = SortationContext.GivenServices();
var sortationProvider = services.WhenGetSortationProvider();
var sortations = new List<Sortation>();
var sortation = new Sortation { CategoryId = categoryId };
// the key moq configuration here
services.MockSortationService.Setup(x => x.ListAsync(It.IsAny<string>())).Returns(Task.FromResult(sortations));
// Act
await sortationProvider.SaveAsync(sortation);
// Assert
sortation.Order.Should().Be(0);
}
public class SortationProvider
{
private SortationService _sortationService;
public SortationProvider()
{
_sortationService = new SortationService();
}
public async Task<Sortation> SaveAsync(Sortation sortation)
{
if (sortation.Id == 0)
{
var sortations = await ListAsync(sortation.CategoryId);
sortation.Order = sortations.Count;
_sortationService.Create(sortation);
}
else
{
_sortationService.Update(sortation);
}
await _sortationService.SaveChangesAsync();
return sortation;
}
// should be virtual
public virtual async Task<List<Sortation>> ListAsync(string categoryId, params string[] includes) =>
await _sortationService.List(includes).Where(m => m.CategoryId.Equals(categoryId)).ToListAsync();
}
public class SortationContext
{
public static Services GivenServices()
{
return new Services();
}
}
public class Services
{
public Services()
{
MockSortationService = new Mock<SortationProvider>();
}
public SortationProvider WhenGetSortationProvider()
{
return MockSortationService.Object;
}
public Mock<SortationProvider> MockSortationService { get; set; }
}
internal class SortationService
{
public void Create(Sortation sortation)
{
}
public void Update(Sortation sortation)
{
}
public Task SaveChangesAsync()
{
return Task.CompletedTask;
}
public DbSet<Sortation> List(string[] includes)
{
throw new NotImplementedException();
}
}
public class Sortation
{
public string CategoryId { get; set; }
public int Id { get; set; }
public int Order { get; set; }
}
The main change is in line that contains Setup
method. I made ListAsync
method virtual also. The main assumption is that List(string[] includes)
method returns DbSet<Sortation>
. Hope it helps.
Upvotes: 0