我试图通过嘲笑来编写单元测试。我的测试是模拟使用 $.ajax({
context: /* element or object which should be `this` at `success` */
})
方法的GetAll
方法。如果我将FirstOrDefaultAsync
更改为FirstOrDefaultAsync
,我的测试工作正常,但当我放回FirstOrDefault
时,它仍会失败。
我的单元测试代码在
之下FirstOrDefaultAsync
我正在尝试测试代码
[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("a@a.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;
}
结果StackTrace:
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
答案 0 :(得分:0)
为了模拟异步查询,您需要实现IDbAsyncQueryProvider
接口。我不知道你是如何实现GenerateMockDbSetForAsync
方法的,但这里完全是在模拟异步方法上完成的。