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

时间:2014-09-15 18:06:30

标签: 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>> 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

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

1 个答案:

答案 0 :(得分:3)

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

        mockItemDbSet.As<IQueryable<Item>>().Setup(m => m.GetEnumerator()).Returns(() =>
        {
            var enumerator = items.GetEnumerator();
            enumerator.Reset();
            return enumerator;
        });