【发布时间】: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);
我已经用数据填充了ParentTable 和ChildTable。如果我删除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