C# Foreach noop隐藏模拟Dbset中的所有元素

C# Foreach noop隐藏模拟Dbset中的所有元素,c#,entity-framework,unit-testing,moq,entity-framework-6,C#,Entity Framework,Unit Testing,Moq,Entity Framework 6,我正在我的应用程序中编写单元测试,它使用EntityFramework和Moq进行单元测试。在测试“GetAll”场景时,我发现尽管我模拟了一组3项,但没有一项返回。我缩减了代码,发现foreach执行清除了我的DbSet。这是什么原因造成的,我如何修复它 IQueryable<Item> items = new List<Item>() { new Item() }.AsQueryable(); Mock<DbSet<Item>> m

我正在我的应用程序中编写单元测试,它使用EntityFramework和Moq进行单元测试。在测试“GetAll”场景时,我发现尽管我模拟了一组3项,但没有一项返回。我缩减了代码,发现foreach执行清除了我的DbSet。这是什么原因造成的,我如何修复它

IQueryable<Item> items = new List<Item>() {
    new Item()
 }.AsQueryable();

Mock<DbSet<Item>> mockItemDbSet = new Mock<DbSet<Item>>();
mockItemDbSet.As<IQueryable<Item>>().Setup(m => m.Provider).Returns(items.Provider);
mockItemDbSet.As<IQueryable<Item>>().Setup(m => m.Expression).Returns(items.Expression);
mockItemDbSet.As<IQueryable<Item>>().Setup(m => m.ElementType).Returns(items.ElementType);
mockItemDbSet.As<IQueryable<Item>>().Setup(m => m.GetEnumerator()).Returns(items.GetEnumerator());
DbSet<Item> itemDbSet = mockItemDbSet.Object;

CompanyContext context = Mock.Of<CompanyContext>(c =>
    c.Items == mockItemDbSet.Object
);

//itemDbSet has a single item
foreach (var item in context.Items) {}
//itemDbSet is empty
IQueryable项目=新列表(){
新项目()
}.AsQueryable();
Mock mockItemDbSet=new Mock();
mockItemDbSet.As().Setup(m=>m.Provider).返回(items.Provider);
mockItemDbSet.As().Setup(m=>m.Expression).Returns(items.Expression);
mockItemDbSet.As().Setup(m=>m.ElementType).Returns(items.ElementType);
mockItemDbSet.As().Setup(m=>m.GetEnumerator()).Returns(items.GetEnumerator());
DbSet itemDbSet=mockItemDbSet.Object;
CompanyContext context=Mock.Of(c=>
c、 Items==mockItemDbSet.Object
);
//itemDbSet只有一个项
foreach(context.Items中的var项){}
//ItemDset为空

编辑:更多的信息,更具体地说是关于itemDbSet有一个项目,然后是空的。在foreach之前,itemDbSet.Count()是1,itemDbSet.ToArray().Count()是1。当然,这是有道理的。在foreach之后,itemDbSet.Count()为1,itemDbSet.ToArray().Count()为0。魔术师在哪里表演这个魔术?

检查项目计数一次后,枚举器在末尾,需要重置。将设置更改为此以重置枚举数

        mockItemDbSet.As<IQueryable<Item>>().Setup(m => m.GetEnumerator()).Returns(() =>
        {
            var enumerator = items.GetEnumerator();
            enumerator.Reset();
            return enumerator;
        });
mockItemDbSet.As().Setup(m=>m.GetEnumerator())。返回(()=>
{
var枚举器=items.GetEnumerator();
枚举数。重置();
返回枚举器;
});

检查项目计数一次后,枚举器位于末尾,需要重置。将设置更改为此以重置枚举数

        mockItemDbSet.As<IQueryable<Item>>().Setup(m => m.GetEnumerator()).Returns(() =>
        {
            var enumerator = items.GetEnumerator();
            enumerator.Reset();
            return enumerator;
        });
mockItemDbSet.As().Setup(m=>m.GetEnumerator())。返回(()=>
{
var枚举器=items.GetEnumerator();
枚举数。重置();
返回枚举器;
});

哦,太棒了!是的,将GetEnumerator设置替换为您提供的设置可以防止DbSet为“空”。这也为Visual Studio提到的“扩展结果视图将枚举IEnumerable”带来了一些启发。很好,非常感谢。亲爱的上帝,我刚刚花了2个小时试图模拟第一种方法,认为它是这样,然后我发现了这个。谢谢你让我度过了美好的一天!不知道这是否真的很明显,因为它没有更多的要点:哦,太棒了!是的,将GetEnumerator设置替换为您提供的设置可以防止DbSet为“空”。这也为Visual Studio提到的“扩展结果视图将枚举IEnumerable”带来了一些启发。很好,非常感谢。亲爱的上帝,我刚刚花了2个小时试图模拟第一种方法,认为它是这样,然后我发现了这个。谢谢你让我度过了美好的一天!不知道这是否真的很明显,因为它没有更多的要点:o