【问题标题】:Unit Testing Get with Include 'Value cannot be null'单元测试获取包含“值不能为空”
【发布时间】:2016-10-19 12:37:11
【问题描述】:

我正在使用 Moq 对 get 调用进行单元测试。我正在使用 Automapper 从 SQL 数据库中提取数据并将其映射到我的视图模型中。我的方法看起来像这样:

public virtual IEnumerable<ViewParentTable> Get()
{
    Mapper.CreateMap<ParentTable, ViewParentTable>();
    Mapper.CreateMap<ChildTable, ViewChildTable>()

    IEnumerable<ViewParentTable> tableresult = db.ParentTable
         .Include("ChildTable")
         .Project().To<ViewParentTable>();

    return tableresult;
}

我的测试看起来像这样:

[TestMethod]
public void Get()
{
    IEnumerable<ViewParentTable> returned = method.Get();
    mockContext.VerifyGet(m => m.ParentTable);
}

我已经这样模拟了 DbContext:

this.mockParentSet = new Mock<DbSet<ParentTable>>();
this.mockChildSet = new Mock<DbSet<ChildTable>>();

mockParentSet.As<IQueryable<ParentTable>>().Setup(m => m.Provider).Returns(mockParentData.Provider);
mockParentSet.As<IQueryable<ParentTable>>().Setup(m => m.Expression).Returns(mockParentData.Expression);
mockParentSet.As<IQueryable<ParentTable>>().Setup(m => m.ElementType).Returns(mockParentData.ElementType);
mockParentSet.As<IQueryable<ParentTable>>().Setup(m => m.GetEnumerator()).Returns(mockParentData.GetEnumerator());

mockChildSet.As<IQueryable<ChildTable>>().Setup(m => m.Provider).Returns(mockChildData.Provider);
mockChildSet.As<IQueryable<ChildTable>>().Setup(m => m.Expression).Returns(mockChildData.Expression);
mockChildSet.As<IQueryable<ChildTable>>().Setup(m => m.ElementType).Returns(mockChildData.ElementType);
mockChildSet.As<IQueryable<ChildTable>>().Setup(m => m.GetEnumerator()).Returns(mockChildData.GetEnumerator());

this.mockContext = new Mock<MyContext>();
this.mockContext.Setup(m => m.ParentTable).Returns(mockParentSet.Object);
this.mockContext.Setup(m => m.ChildTable).Returns(mockChildSet.Object);

我已经用数据填充了ParentTableChildTable。如果我删除Include("ChildTable"),则测试通过。但是,使用Include("ChildTable") 会在db 调用Value cannot be null 上引发异常。 Child 和 Parent 表中的所有不可为空的字段都已填充,所以我不确定是什么导致了错误。

【问题讨论】:

  • 我不知道 Moq 如何处理模拟 DbSet,但是对于我使用过的其他模拟框架,你必须意识到它们实际上不是数据库,所以它们不会做包含相关数据所必需的连接。相反,您必须使用完整的对象图加载它们,以便它们可以将其吐出,就好像真实数据库已加入数据一样。
  • 是的,我正在处理。当我构造测试数据时,我循环遍历ParentTable 的每个元素并根据id 分配item.ChildItems。同样,我循环遍历ChildTable的每个元素,并根据id分配item.ParentItem
  • 我不认为这个测试增加了任何价值。你现在不只是在测试 AutoMapper 吗?
  • 这是我正在做的简化版本。关键是它永远不会到达VerifyGet,因为它在执行该方法时会引发异常。
  • 我也有同样的问题。你成功了吗?

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


【解决方案1】:

我设法通过关注answer 使其工作

mockParentSet.Setup(m => m.Include(It.IsAny<string>())).Returns(mockParentSet.Object);

【讨论】:

    猜你喜欢
    • 2019-01-02
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多