【问题标题】:Why is my moq db object yielding no results为什么我的 moq db 对象没有产生任何结果
【发布时间】:2015-11-04 14:30:15
【问题描述】:

我有一个 moq 数据库,其中包含读取序列化实体的 json 文件并将它们反序列化为 moq dbset 的方法。当我设置 dbcontext 时,一个表具有所有预期结果,而另一个表具有 0 个结果。我的 Json 文件格式正确并经过验证,有 5 个条目。

    var airportLocationMoq = GetMockDbSet<Repository.Location>(@"Files/ObjectJson/Airports.json");
    var storageAreaMoq = GetMockDbSet<Repository.StorageArea>(@"Files/ObjectJson/StorageAreas.json");
    var dbContext = new Mock<DbContext>();
    dbContext.Setup(x => x.Locations).Returns(airportLocationMoq.Object);
    dbContext.Setup(x => x.StorageAreas).Returns(storageAreaMoq.Object);

    var airportsFromDb = dbContext.Object.Locations.Where(x => x.Type == 1).ToList();
    var storageAreasFromDb = dbContext.Object.StorageAreas.ToList(); //<-this results in 0 entries however there should be 5.

这些是读取 json 文件并将其反序列化为 moq dbset 的方法:

public string LoadFile(string path)
        {
            return File.ReadAllText(path);
        }

        public List<T> GetData<T>(string path)
        {
            string json = LoadFile(path);
            var dataList = JsonConvert.DeserializeObject<List<T>>(json);

            return dataList;
        }

        public Mock<DbSet<T>> GetMockDbSet<T>(string path) where T : class
        {
            var data = GetData<T>(path).AsQueryable();

            var mockSet = new Mock<DbSet<T>>();
            mockSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(data.Provider);
            mockSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(data.Expression);
            mockSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(data.ElementType);
            mockSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

            return mockSet;

        }

当我在“return mockSet”对象中设置断点并打开结果视图时,数据存在,列表已正确填充,但如果我将光标移开然后返回并展开结果查看数据已消失,并显示“枚举未产生任何结果”。如果我什至没有移动断点,这怎么可能。我实际上只是扩展了结果视图以查看数据,将鼠标光标移开,然后在同一实例中重新钻入,数据就消失了。提供屏幕截图。

【问题讨论】:

  • 您是否尝试过更改文件路径中的斜杠?即@"Files\ObjectJson\StorageAreas.json" => @"Files/ObjectJson/StorageAreas.json"
  • @RDay 是的,我有,但无济于事。

标签: c# entity-framework unit-testing mocking moq


【解决方案1】:

实际的问题在于模拟的初始化方式。

mockSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

此设置为每个 GetEnumerator 函数调用返回相同的枚举器。枚举项目后,枚举器不会为后续调用产生更多结果。

需要修改设置以使用 lambda 表达式。这样,对于每个 GetEnumerator 函数调用,都会返回一个新的枚举数实例。

mockSet.As<IQueryable<T>>()
    .Setup(m => m.GetEnumerator()).Returns(() => data.GetEnumerator());

我最初关于显式 IEnumerable&lt;T&gt; 实现的假设是错误的。

DbSet&lt;T&gt; 类没有任何ToList() 方法。转换 DbSet&lt;T&gt; 到列表 IEnumerable&lt;T&gt;.ToList() 方法是 用过。

接口IEnumerable&lt;T&gt;DbSet&lt;T&gt;类实现 explicitly。所以我认为,你需要设置你的Mock&lt;DbSet&lt;T&gt;&gt;IEnumerable&lt;T&gt; 返回正确的枚举数 界面。

mockSet.As<IEnumerable<T>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

【讨论】:

  • 我也添加了,但它不能解决问题。问题是当我断点并在 Dbset 方法中到达返回模拟集时,数据存在,如果我将鼠标移开然后返回到它,列表是空的,说明“枚举没有产生结果”,而在一秒钟前结果视图充满了条目。它如何包含数据,然后在不离开断点的情况下删除数据?
  • @TheAkhemist 请查看更新后的答案。问题出在Mock&lt;DbSet&lt;T&gt;&gt; 设置中。
  • 是的!这做到了! @LukasKabrt 先生您是国王!谢谢!
  • 你是我今天的英雄,感谢@Lukas为此搜索了几个小时
  • 衷心感谢你,心。我不知道为什么这是真的Once items are enumerated, the enumerator yields no more results for subsequent calls. 但你的解决方案有效!我以为我疯了,现在数据在这里,我再看一遍,它就不见了。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-24
  • 1970-01-01
  • 1970-01-01
  • 2017-11-26
  • 2020-09-23
  • 2019-02-03
  • 2022-11-20
相关资源
最近更新 更多