我正在尝试使用 Entity Framework 和 SQL Server 托管在 Azure 上的 MVC 网络应用程序。我正在尝试为单元测试设置它,我正在使用 Moq 来模拟 DbContext 并遇到一些问题。我有以下模型:
class Employee
{
[Key]
public int EmployeeID{get;set;}
[ForeignKey("Business")]
public int BusinessID {get;set;}
public virtual Business {get;set;}
}
class Business
{
public Business()
{
Employees = new HashSet<Employee>();
}
[Key]
public int BusinessID{get;set;}
public virtual ICollection<Employee> Employees{get;set;}
}
这样我就可以遍历一家企业的所有员工,也可以询问特定员工他的雇主是谁。
所以当我开始模拟测试数据时,我模拟了 DbContext:
var mockContext = Mock<MyDbContext>();
然后我创建了一些测试数据集:
List<Business> businesses = new List<Business>();
Business business1 = new Business();
business1.Name = "TestBusiness"
...
然后模拟 DbSet for Business(所以 MyDbContext.Businesses 是非空的):
var queryableTestData = businesses.AsQueryable();
var mockSet = new Mock<DbSet<Business>();
mockSet.As<IDbSet<Business>>().Setup(m => m.Provider).Returns(queryableTestData.Provider);
mockSet.As<IDbSet<Business>>().Setup(m => m.Expression).Returns(queryableTestData.Expression);
mockSet.As<IDbSet<Business>>().Setup(m => m.ElementType).Returns(queryableTestData.ElementType);
mockSet.As<IDbSet<Business>>().Setup(m => m.GetEnumerator()).Returns( () => queryableTestData.GetEnumerator());
mockSet.As<IDbSet<Business>>().Setup(m => m.Local).Returns( mockSet.Object.Local );
并将其绑定(bind)到模拟 DbContext 中:
mockContext.Setup(context => context.Businesses).Returns(mockSet.Object);
mockContext.Setup(context => context.Set<T>()).Returns(mockSet.Object);
我做同样的事情来创建一些测试员工数据。我面临的问题是 Business.Employees
集合总是返回空,即使集合中可能存在通常在正常操作期间填充的数据(即存在一些 BusinessID == 1 的 Employee 和一些BusinessID == 1 的业务存在,但 Business.Employees 仅在测试时为空)。
除了手动建立所有实体关系(即:business.Employees = myTestEmployeeList.Where(e => e.BusinessID == business.BusinessID);
),我还有其他选择吗?我想一旦对象关系非常重要,这种方法将难以管理。我希望我做错了什么,有人可以指出我的错误 :) 感谢您的帮助和时间!
最佳答案
这是一个经典问题。我认为您有两个选择。
- 处理它并根据需要手动设置关系
- 不要尝试模拟数据库,而是使用 SQLLite 作为测试的后端, Entity Framework 可以在此基础上发挥其魔力。
2 的缺点是它可以为额外的设置和配置问题增加相当大的执行时间,这会弹出并咬你的屁股。
我个人更喜欢选项 1。
关于asp.net-mvc - 在 EntityFramework 和 Moq 中模拟模型集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33376405/