Wie zum Hohn ein async-repository mit Entity Framework-Core

Ich versuche zum erstellen einer unit test für eine Klasse, die Aufrufe in einer async-repository. Ich bin mit ASP.NET Kern-und Entity Framework-Kern. Mein generischen repository sieht wie folgt aus.

public class EntityRepository<TEntity> : IEntityRepository<TEntity> where TEntity : class
{
    private readonly SaasDispatcherDbContext _dbContext;
    private readonly DbSet<TEntity> _dbSet;

    public EntityRepository(SaasDispatcherDbContext dbContext)
    {
        _dbContext = dbContext;
        _dbSet = dbContext.Set<TEntity>();
    }

    public virtual IQueryable<TEntity> GetAll()
    {
        return _dbSet;
    }

    public virtual async Task<TEntity> FindByIdAsync(int id)
    {
        return await _dbSet.FindAsync(id);
    }

    public virtual IQueryable<TEntity> FindBy(Expression<Func<TEntity, bool>> predicate)
    {
        return _dbSet.Where(predicate);
    }

    public virtual void Add(TEntity entity)
    {
        _dbSet.Add(entity);
    }
    public virtual void Delete(TEntity entity)
    {
        _dbSet.Remove(entity);
    }

    public virtual void Update(TEntity entity)
    {
        _dbContext.Entry(entity).State = EntityState.Modified;
    }

    public virtual async Task SaveChangesAsync()
    {
        await _dbContext.SaveChangesAsync();
    }
}

Dann habe ich eine service-Klasse, die Aufrufe FindBy und FirstOrDefaultAsync auf eine Instanz des Repositorys:

    public async Task<Uri> GetCompanyProductURLAsync(Guid externalCompanyID, string productCode, Guid loginToken)
    {            
        CompanyProductUrl companyProductUrl = await _Repository.FindBy(u => u.Company.ExternalCompanyID == externalCompanyID && u.Product.Code == productCode.Trim()).FirstOrDefaultAsync();

        if (companyProductUrl == null)
        {
            return null;
        }

        var builder = new UriBuilder(companyProductUrl.Url);
        builder.Query = $"-s{loginToken.ToString()}";

        return builder.Uri;
    }

Ich versuche zu verspotten, die repository-Aufruf in meinem test unter:

    [Fact]
    public async Task GetCompanyProductURLAsync_ReturnsNullForInvalidCompanyProduct()
    {
        var companyProducts = Enumerable.Empty<CompanyProductUrl>().AsQueryable();

        var mockRepository = new Mock<IEntityRepository<CompanyProductUrl>>();
        mockRepository.Setup(r => r.FindBy(It.IsAny<Expression<Func<CompanyProductUrl, bool>>>())).Returns(companyProducts);

        var service = new CompanyProductService(mockRepository.Object);

        var result = await service.GetCompanyProductURLAsync(Guid.NewGuid(), "wot", Guid.NewGuid());

        Assert.Null(result);
    }

Jedoch, wenn der test führt der Aufruf der repository, bekomme ich die folgende Fehlermeldung:

The provider for the source IQueryable doesn't implement IAsyncQueryProvider. Only providers that implement IEntityQueryProvider can be used for Entity Framework asynchronous operations.

Wie kann ich richtig das mock-repository, um diese zu arbeiten?

Vielleicht kann dies helfen, msdn.microsoft.com/en-us/library/dn314429.aspx
Lesen Sie den Abschnitt auf Testing with async queries
Sie müssen simulieren beide IQueryable<T> und IAsyncEnumerableAccessor<T> Schnittstellen sowie

InformationsquelleAutor Jed Veatch | 2016-11-07

Schreibe einen Kommentar