![](/img/trans.png)
[英]Argument 1: cannot convert from 'Moq.Mock<System.Data.Entity.DbContext>' to 'System.Data.Entity.DbContext'
[英]Accessing Moq Mock Data from DbContext disappears when called twice?
我试图了解我的应用程序中正在发生的行为。 我已经DbContext
了我的DbContext
,当我进行调用时,从dbContext.Set<T>().ToList()
获取项目,第二次调用不包含我的模拟数据。 我不确定为什么会发生这种情况,因为该数据应该仍然存在。 请参见下面的代码:
SUT:
public class Employee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public decimal Salary { get; set; }
}
public class EmployeeDb
: DbContext
{
public EmployeeDb()
{
}
public virtual IDbSet<Employee> Employees { get; set; }
}
单元测试:
public class MockDatabase
{
public Mock<EmployeeDb> SetMockData()
{
var mockDb = new Mock<EmployeeDb>();
mockDb.Setup(i => i.Set<Employee>()).Returns(GetMockSet(Employees).Object);
mockDb.SetupGet(i => i.Employees).Returns(() => GetMockSet(Employees).Object);
return mockDb;
}
private List<Employee> _providers;
private List<Employee> Employees => _providers ?? (_providers = new List<Employee>
{
GetEmployee(1),
GetEmployee(2),
GetEmployee(3),
GetEmployee(4),
GetEmployee(5),
});
private static Employee GetEmployee(int id)
{
return new Employee
{
FirstName = Faker.Name.First(),
LastName = Faker.Name.Last(),
Age = Faker.RandomNumber.Next(50),
Id = id,
Salary = Faker.RandomNumber.Next(100000)
};
}
#region Hood
public static Mock<DbSet<T>> GetMockSet<T>(IList<T> items) where T : class
{
var querable = items.AsQueryable();
var mockSet = new Mock<DbSet<T>>();
mockSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(querable.Provider);
mockSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(querable.Expression);
mockSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(querable.ElementType);
mockSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(querable.GetEnumerator());
mockSet.Setup(i => i.Add(It.IsAny<T>())).Callback(delegate (T item) {
items.Add(item);
});
return mockSet;
}
#endregion
}
[TestClass]
public class UnitTest1
{
private EmployeeDb _context;
[TestInitialize]
public void TestInitialize()
{
var mockDb = new MockDatabase();
_context = mockDb.SetMockData().Object;
}
[TestMethod]
public void Test_CallTwice_ReturnsEqualCount()
{
var emps = _context.Set<Employee>().ToList();
var emps2 = _context.Set<Employee>().ToList();
Assert.IsTrue(emps.Count == emps2.Count);
// -- This works
//var empCount = _context.Set<Employee>().Count();
//var empCount2 = _context.Set<Employee>().Count();
//Assert.IsTrue(empCount == empCount2);
}
}
我有没有关于此代码的东西吗? Moq与ToList()
吗?
ToList
在调用时枚举集合,但枚举器仅向前,因此在第一次调用之后,它已经在末尾。
设置GetEnumerator
使用Returns
函数的重载,以允许其他方式的多次调用,每次都会返回同一枚举数,并且您会获得所遇到的行为。
mockSet.As<IQueryable<T>>()
.Setup(m => m.GetEnumerator())
.Returns(() => querable.GetEnumerator()); //<-- function
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.