枚举 DbSet 枚举后不会 return 到列表的开头
Enumerating DbSet doesn't return to the beginning of the list after enumeration
我正在使用 Moq 在测试中将 Entity Framework Core 的 DbSet 模拟为 return 个项目。
我进行了一项测试,该测试获取数据库集中的第一项并检查其计数。第一次,我设法得到存储在 DbSet
中的对象,计数为 1。第二次,我在 return 中得到 null,但集合的计数仍然是 1。当我调试并检查,DbSet 中的集合给出了一条消息“Enumeration yielded no results”
[TestMethod]
public void MyTest()
{
var dbMock = GetDbContextMock();
Assert.AreEqual(1, dbMock.Object.Table2.Count()); //passes
Table2Model item1 = dbMock.Object.Table2.AsEnumerable().Where(x => x.DataCenter == "DataCenter").FirstOrDefault(); // item1 is an object
Assert.AreEqual(1, dbMock.Object.CurrentRunningServices.Count()); //passes
Table2Model item2 = dbMock.Object.Table2.AsEnumerable().Where(x => x.DataCenter == "DataCenter").FirstOrDefault(); //item2 is null
Assert.AreEqual(1, dbMock.Object.CurrentRunningServices.Count()); //passes
}
为什么我第二次得到的是null而不是对象?感觉好像某个地方的某个内部指针没有回到 DbSet 集合的开始。
实施:
private List<Table2Model> GetMockTable2List()
{
Table2Model item = new Table2Model();
item.DataCenter = "DataCenter";
return new List<Table2Model>() { item } ;
}
private Mock<MyDbContext> GetDbContextMock()
{
var realDal = new MyDbContext();
var dbContextMock = new Mock<MyDbContext>();
dbContextMock.SetupAllProperties();
dbContextMock.Object.Table1= realDal.Table1;
var table2List = GetMockTable2List().AsQueryable();
var table2DbSetMock = new Mock<DbSet<Table2Model>>();
table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.Provider).Returns(table2List.Provider);
table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.Expression).Returns(table2List.Expression);
table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.ElementType).Returns(table2List.ElementType);
table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.GetEnumerator()).Returns(table2List.GetEnumerator());
dbContextMock.Object.Table2 = table2DbSetMock.Object;
return dbContextMock;
}
线路有问题
table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.GetEnumerator()).Returns(table2List.GetEnumerator());
它 returns 每次都是相同的枚举器。修复它的方法是将 Returns
值更改为 lambda:
table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.GetEnumerator()).Returns(() => table2List.GetEnumerator());
我正在使用 Moq 在测试中将 Entity Framework Core 的 DbSet 模拟为 return 个项目。
我进行了一项测试,该测试获取数据库集中的第一项并检查其计数。第一次,我设法得到存储在 DbSet
中的对象,计数为 1。第二次,我在 return 中得到 null,但集合的计数仍然是 1。当我调试并检查,DbSet 中的集合给出了一条消息“Enumeration yielded no results”
[TestMethod]
public void MyTest()
{
var dbMock = GetDbContextMock();
Assert.AreEqual(1, dbMock.Object.Table2.Count()); //passes
Table2Model item1 = dbMock.Object.Table2.AsEnumerable().Where(x => x.DataCenter == "DataCenter").FirstOrDefault(); // item1 is an object
Assert.AreEqual(1, dbMock.Object.CurrentRunningServices.Count()); //passes
Table2Model item2 = dbMock.Object.Table2.AsEnumerable().Where(x => x.DataCenter == "DataCenter").FirstOrDefault(); //item2 is null
Assert.AreEqual(1, dbMock.Object.CurrentRunningServices.Count()); //passes
}
为什么我第二次得到的是null而不是对象?感觉好像某个地方的某个内部指针没有回到 DbSet 集合的开始。
实施:
private List<Table2Model> GetMockTable2List()
{
Table2Model item = new Table2Model();
item.DataCenter = "DataCenter";
return new List<Table2Model>() { item } ;
}
private Mock<MyDbContext> GetDbContextMock()
{
var realDal = new MyDbContext();
var dbContextMock = new Mock<MyDbContext>();
dbContextMock.SetupAllProperties();
dbContextMock.Object.Table1= realDal.Table1;
var table2List = GetMockTable2List().AsQueryable();
var table2DbSetMock = new Mock<DbSet<Table2Model>>();
table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.Provider).Returns(table2List.Provider);
table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.Expression).Returns(table2List.Expression);
table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.ElementType).Returns(table2List.ElementType);
table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.GetEnumerator()).Returns(table2List.GetEnumerator());
dbContextMock.Object.Table2 = table2DbSetMock.Object;
return dbContextMock;
}
线路有问题
table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.GetEnumerator()).Returns(table2List.GetEnumerator());
它 returns 每次都是相同的枚举器。修复它的方法是将 Returns
值更改为 lambda:
table2DbSetMock.As<IQueryable<Table2Model>>().Setup(m => m.GetEnumerator()).Returns(() => table2List.GetEnumerator());