Mock Entity Framework FindAsync() method
In entity framework, FindAsync() method has signature of:
public virtual ValueTask<TEntity> FindAsync([CanBeNullAttribute] params object[] keyValues);
Assume we have a method in DB repository that looks for brand information by brand ID:
public async Task<Brand> GetBrandbyIdAsync(int brandId)
{
var brand = await _context.Brands.FindAsync(brandId).ConfigureAwait(false);
return brand;
}
In order to make this method work, we need to mock the FindAsync call inside the method:
var dbSetMock = CreateDbSetMock(brands);
dbSetMock.Setup(m => m.FindAsync(It.IsAny<object[]>())).Returns((object[] r) =>
{
return new ValueTask<Brand>(dbSetMock.Object.FirstOrDefaultAsync(b => b.BrandId == (int)r[0]));
});
private static Mock<DbSet<T>> CreateDbSetMock<T>(IEnumerable<T> elements) where T : class
{
var elementsAsQueryable = elements.AsQueryable();
var dbSetMock = new Mock<DbSet<T>>();
dbSetMock.As<IAsyncEnumerable<T>>()
.Setup(x => x.GetAsyncEnumerator(default))
.Returns(new TestAsyncEnumerator<T>(elementsAsQueryable.GetEnumerator()));
dbSetMock.As<IQueryable<T>>()
.Setup(m => m.Provider)
.Returns(new TestAsyncQueryProvider<T>(elementsAsQueryable.Provider));
dbSetMock.As<IQueryable<T>>()
.Setup(m => m.Expression).Returns(elementsAsQueryable.Expression);
dbSetMock.As<IQueryable<T>>()
.Setup(m => m.ElementType).Returns(elementsAsQueryable.ElementType);
dbSetMock.As<IQueryable<T>>()
.Setup(m => m.GetEnumerator()).Returns(elementsAsQueryable.GetEnumerator());
return dbSetMock;
}
Comments