使用Moq模拟IQueryable<T> FindBy接口方法单元测试报错如何解决
问题根源
报错的核心原因是:业务代码中FindBy返回IQueryable后调用了EF Core的异步方法FirstOrDefaultAsync,但你Moq模拟返回的是普通内存集合转换的IQueryable,没有实现异步查询需要的IAsyncQueryProvider、IAsyncEnumerable<T>等接口,调用异步方法时会抛出不支持操作的异常。你的业务逻辑应该捕获了这个异常并生成了Error信息,所以触发了「结果不应包含Error」的断言失败。
修复方案
- 第一步:安装
MockQueryable.Moq包,这个包已经封装了Moq场景下IQueryable异步操作的所有兼容实现,不用手写冗余的接口适配代码:
# NuGet包管理器安装 Install-Package MockQueryable.Moq # dotnet CLI安装 dotnet add package MockQueryable.Moq
- 第二步:修改你的Moq模拟代码,把测试数据转换为支持异步的查询对象:
// list是你准备的测试用NotificationType集合 var asyncQueryable = list.AsQueryable().BuildMock(); repository.Setup(x => x.FindBy(It.IsAny<Expression<Func<NotificationType, bool>>>())) .Returns((Expression<Func<NotificationType, bool>> expression) => asyncQueryable.Where(expression));
修改完成后,后续的Select、FirstOrDefaultAsync操作都可以正常执行,不会抛出异常,Error信息不会产生,断言就可以正常通过。另外你原来的代码里Returns参数不需要做强制类型转换,强转反而可能引入隐式转换的隐患,按照上面的写法直接接收表达式参数即可。
内容的提问来源于stack exchange,提问作者Arvind Agrahari
相关产品推荐
相关产品推荐

