Próbuję utworzyć test jednostki dla klasy, która wywołuje asynchroniczne repozytorium. Używam ASP.NET Core i Entity Framework Core. Moje ogólne repozytorium wygląda tak.Jak wyśmiać repozytorium asynchroniczne z Entity Framework Core
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();
}
}
Następnie mam klasy usług, który wywołuje FindBy i FirstOrDefaultAsync na wystąpienie repozytorium:
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;
}
Próbuję mock repozytorium połączenia w moim teście poniżej:
[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);
}
Jednak, gdy test wykonuje wywołanie do repozytorium, pojawia się następujący błąd:
The provider for the source IQueryable doesn't implement IAsyncQueryProvider. Only providers that implement IEntityQueryProvider can be used for Entity Framework asynchronous operations.
Jak mogę właściwie kpić z repozytorium, aby to działało?
Może być to może pomóc https://msdn.microsoft.com/en-us/library/dn314429.aspx – Nkosi
Przeczytaj sekcję "Testowanie zapytań asynchronicznych" – Nkosi
Musisz sfałszować zarówno interfejsy 'IQueryable' jak i 'IAsyncEnumerableAccessor ' –
Dealdiane