Исходный IQueryable не реализует IDbAsyncEnumerable при попытке макета - PullRequest
0 голосов
/ 04 сентября 2018

Я пытаюсь проверить немного кода, который у меня есть:

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;
}

Метод ListAsync вызывает у меня проблему. Я настроил свой тест так:

[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);
}

И когда я запускаю это, я получаю эту ошибку:

Сообщение: System.InvalidOperationException: исходный код IQueryable не реализует IDbAsyncEnumerable. Только источники, которые реализуют IDbAsyncEnumerable, могут использоваться для асинхронных операций Entity Framework.

В соответствии с этим: Для асинхронных операций Entity Framework могут использоваться только источники, реализующие IAsyncEnumerable Мне нужно добавить EF в мой проект UnitTest, что я и сделал. Но ошибка все еще сохраняется.

Метод ListAsync выглядит следующим образом:

public async Task<List<Sortation>> ListAsync(string categoryId, params string[] includes) => 
    await _sortationService.List(includes).Where(m => m.CategoryId.Equals(categoryId)).ToListAsync();

Кто-нибудь знает, как я могу предотвратить возникновение этой ошибки?

1 Ответ

0 голосов
/ 12 сентября 2018

Не знаю, если вопрос все еще актуален, но все же. Я согласен с комментарием Марка, однако вот пример, который работает для меня. Я добавил несколько разумных реализаций заглушки для упомянутого класса, потому что здесь нет подробностей. Я могу ошибаться в своих предположениях:

[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; }
}

Основное изменение в строке, содержащей Setup метод. Я также сделал виртуальный метод ListAsync. Основное предположение заключается в том, что метод List(string[] includes) возвращает DbSet<Sortation>. Надеюсь, это поможет.

...