mam tej metody:Testowanie EF metody asynchroniczne z metod synchronizacji z MOQ
public async Task DeleteUserAsync(Guid userId)
{
using (var context = this.contextFactory.Create())
{
var user = await context.Users.FirstOrDefaultAsync(x => x.Id.Equals(userId));
if (user == null)
{
throw new Exception("User doesn't exist");
}
context.Users.Remove(user);
await context.SaveChangesAsync();
}
}
Chcę przetestować go. Więc tworzę test:
[TestMethod]
public async Task DeleteUsersSuccessfulCallTest()
{
// Arrange
var id = Guid.NewGuid();
var user = new User() { Id = id };
var context = new Mock<IDashboardContext>();
var usersDbSet = DbSetQueryMocking.GenericSetupAsyncQueryableMockInterfaceSet(new List<User> { user }.AsQueryable());
context.Setup(x => x.Users).Returns(usersDbSet.Object);
context.Setup(x => x.Users.Remove(user)).Returns(user).Verifiable();
context.Setup(x => x.SaveChangesAsync()).ReturnsAsync(1).Verifiable();
this.contextFactory.Setup(x => x.Create()).Returns(context.Object);
// Act
await this.userService.DeleteUserAsync(id);
context.VerifyAll();
}
}
Mam tej metody, aby stworzyć mi próbny zestaw:
public static Mock<DbSet<T>> GenericSetupAsyncQueryableMockSet<T>(IQueryable<T> data) where T : class
{
var mockSet = new Mock<DbSet<T>>();
mockSet.As<IDbAsyncEnumerable<T>>().Setup(m => m.GetAsyncEnumerator()).Returns(new TestDbAsyncEnumerator<T>(data.GetEnumerator()));
mockSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(new TestDbAsyncQueryProvider<T>(data.Provider));
mockSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
return mockSet;
}
Jednakże, ponieważ moja DeleteUserAsync
zawiera metody rozszerzenie async i standardowych metod synchronizacji otrzymuję komunikat o błędzie :
System.InvalidOperationException: dostawca dla źródłowego produktu IQueryable nie implementuje obiektu IDbAsyncQueryProvider. Tylko dostawcy implementujący IDbAsyncQueryProvider mogą być używane do asynchronicznych operacji Entity Framework. Aby uzyskać więcej informacji, patrz http://go.microsoft.com/fwlink/?LinkId=287068.
Oczywiście gdybym tylko skonfigurować DbSet<T>
z Queryable
wyśmiewali się wtedy będzie rzucać ten sam wyjątek.
FYI: linia wykraczająca jest:
context.Setup(x => x.Users.Remove(user)).Returns(user).Verifiable();
Z tej linii: błędy
Bez niej: udane testy.
Jak to naprawić?
To najprawdopodobniej problem z szyderstwem i nie ma nic wspólnego z EF ani testowaniem. – Euphoric
Mam zaktualizowane pytanie odzwierciedlające ten –
https://msdn.microsoft.com/en-us/data/dn314429#async – Ali