0
我想通过嘲笑编写单元测试。我的测试是嘲笑使用FirstOrDefaultAsync
方法的GetAll
方法。如果我将FirstOrDefaultAsync
更改为FirstOrDefault
我的测试正常,但当我放回FirstOrDefaultAsync
时仍然失败。使用NSubstitute,实体框架嘲弄FirstOrDefualtAscync方法抛出异常
我的单元测试代码如下
[TestMethod]
public async Task GetAsync_WithUser_ReturnsOk()
{
var data = GetUserResult();
var mockContext = Substitute.For<IPostAnythingContext>();
var mockSet = data.GenerateMockDbSetForAsync();
mockContext.Users.Returns(mockSet);
uow.User.GetAll().Returns(data);
var result = await sut.GetAsync("[email protected].com");
}
代码我试图测试
public async Task<Result<Users>> GetAsync(string email)
{
var result = Uow.User.GetAll()
.Where(x => x.EmailAddress == email)
.Include(x => x.UsersUsersTypes);
return Result.Ok(await result.FirstOrDefaultAsync());
}
我的扩展方法
public static DbSet<TEntity> GenerateMockDbSetForAsync<TEntity>(this IEnumerable<TEntity> queryableEnumerable) where TEntity : class
{
var queryable = queryableEnumerable as IQueryable<TEntity> ?? queryableEnumerable.AsQueryable();
var mockSet = Substitute.For<DbSet<TEntity>, IQueryable<TEntity>, IDbAsyncEnumerable<TEntity>>();
// async support
var castMockSet = (IQueryable<TEntity>)mockSet;
var castAsyncEnum = (IDbAsyncEnumerable<TEntity>)mockSet;
castAsyncEnum.GetAsyncEnumerator().Returns(new TestDbAsyncEnumerator<TEntity>(queryable.GetEnumerator()));
castMockSet.Provider.Returns(new TestDbAsyncQueryProvider<TEntity>(queryable.Provider));
castMockSet.Expression.Returns(queryable.Expression);
castMockSet.ElementType.Returns(queryable.ElementType);
castMockSet.GetEnumerator().Returns(queryable.GetEnumerator());
return mockSet;
}
异常我越来越
Test Name: GetAsync_WithUser_ReturnsOk
Test FullName: PostAnything.Business.Tests.UsersServiceTests.GetAsync_WithUser_ReturnsOk
Test Source: C:\TFS\PostAnything\PostAnything.Business.Tests\UsersServiceTests.cs : line 40
Test Outcome: Failed
Test Duration: 0:00:02.5118084
结果堆栈跟踪:
at System.Data.Entity.QueryableExtensions.FirstOrDefaultAsyncTSource
at System.Data.Entity.QueryableExtensions.FirstOrDefaultAsyncTSource
at PostAnything.Business.Implementation.UsersService.d__2.MoveNext() in C:\TFS\PostAnything\PostAnything.Business\Implementation\UsersService.cs:line 28
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at PostAnything.Business.Tests.UsersServiceTests.d__5.MoveNext() in C:\TFS\PostAnything\PostAnything.Business.Tests\UsersServiceTests.cs:line 49
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Result Message:
Test method PostAnything.Business.Tests.UsersServiceTests.GetAsync_WithUser_ReturnsOk threw exception:
System.InvalidOperationException: The provider for the source IQueryable doesn't implement IDbAsyncQueryProvider. Only providers that implement IDbAsyncQueryProvider can be used for Entity Framework asynchronous operations. For more details see http://go.microsoft.com/fwlink/?LinkId=287068.
我已经尝试过这一点,但得到了同样的错误,但我已经更新了我的扩展方法问题 –
查询更改为'Uow.User.GetAll()。其中(x = > x.EmailAddress == email)'并检查它是否有效。 –
如果您要在我的代码中更改该查询,我试图测试它, –