You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Moq模拟Entity Framework Core的DbSet二次枚举返回null问题咨询

问题原因

你遇到的问题根源是IQueryable.GetEnumerator()方法的Mock配置错误:

  • 你当前的配置写法.Returns(table2List.GetEnumerator())会在Mock初始化阶段就一次性生成一个固定的枚举器实例,后续所有对GetEnumerator()的调用都会复用这同一个枚举器
  • 枚举器是单向迭代的,第一次查询完成后枚举器的内部指针已经移动到集合末尾,第二次查询复用同一个枚举器自然读取不到任何元素,所以返回null
  • 而Count()断言能通过的原因是该方法优先走LINQ to Objects的长度优化逻辑,没有触发枚举器迭代。
修复方案

只需要修改GetEnumerator()的Mock配置,改为每次调用时都生成新的枚举器实例即可:
把原来的配置行:

table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.GetEnumerator()).Returns(table2List.GetEnumerator());

替换为带lambda表达式的重载,让每次调用都返回新的枚举器:

table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.GetEnumerator()).Returns(() => table2List.GetEnumerator());
补充说明

如果是EF Core 3.0+版本的模拟场景,还需要额外适配IAsyncEnumerable<T>接口的实现,避免异步查询时报错,适配代码如下:

table2DbSetMock.As<IAsyncEnumerable<Table2Model>>()
    .Setup(m => m.GetAsyncEnumerator(It.IsAny<CancellationToken>()))
    .Returns(() => new TestAsyncEnumerator<Table2Model>(table2List.GetEnumerator()));

这里的TestAsyncEnumerator是自定义的异步枚举器实现,你可以根据项目需求自行实现或者引入相关测试辅助类库。

内容的提问来源于stack exchange,提问作者CodeMonkey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 07:24:05