C# 从Moq模拟集获取IQueryable
我尝试使用实体框架和Moq模拟我的上下文来测试我的存储库 我当前在测试我的存储库中的C# 从Moq模拟集获取IQueryable,c#,entity-framework,unit-testing,moq,C#,Entity Framework,Unit Testing,Moq,我尝试使用实体框架和Moq模拟我的上下文来测试我的存储库 我当前在测试我的存储库中的GetSingle查询时遇到问题: public Customer GetSingle(int id, HotelBookingContext context = null, params Expression<Func<Customer, object>>[] navigationProperties) { using (var tempContext = context ??
GetSingle
查询时遇到问题:
public Customer GetSingle(int id, HotelBookingContext context = null, params Expression<Func<Customer, object>>[] navigationProperties)
{
using (var tempContext = context ?? new HotelBookingContext())
{
IQueryable<Customer> dbQuery = tempContext.Set<Customer>();
foreach (Expression<Func<Customer, object>> navigationProperty in navigationProperties)
dbQuery = dbQuery.Include(navigationProperty);
return dbQuery
.AsNoTracking()
.FirstOrDefault(x => x.Id == id);
}
}
public Customer GetSingle(int-id,HotelBookingContext-context=null,params-Expression[]navigationProperties)
{
使用(var tempContext=context??新建HotelBookingContext())
{
IQueryable dbQuery=tempContext.Set();
foreach(navigationProperties中的表达式navigationProperty)
dbQuery=dbQuery.Include(navigationProperty);
返回数据库查询
.AsNoTracking()
.FirstOrDefault(x=>x.Id==Id);
}
}
使用以下测试:
public void GetSingle_QueryingASingleCustomer_ReturnsASingleCustomer()
{
var cus = new Customer() { Email = "testMail", Name = "testName", Id = 1 };
var customer = new List<Customer> {cus}.AsQueryable();
var mockSet = new Mock<DbSet<Customer>>();
mockSet.As<IQueryable<Customer>>().Setup(m => m.Provider).Returns(customer.Provider);
mockSet.As<IQueryable<Customer>>().Setup(m => m.Expression).Returns(customer.Expression);
mockSet.As<IQueryable<Customer>>().Setup(m => m.ElementType).Returns(customer.ElementType);
mockSet.As<IQueryable<Customer>>().Setup(m => m.GetEnumerator()).Returns(customer.GetEnumerator());
var mockContext = new Mock<HotelBookingContext>();
mockContext.Setup(m => m.Customers).Returns(mockSet.Object);
var temp = _customerRepository.GetSingle(cus.Id, mockContext.Object);
Assert.AreEqual(temp.Name, cus.Name);
Assert.AreEqual(temp.Email, cus.Email);
Assert.AreEqual(temp.Id, cus.Id);
}
public void GetSingle\u queryingasingcustomer\u ReturnsASingleCustomer()
{
var cus=new Customer(){Email=“testMail”,Name=“testName”,Id=1};
var customer=新列表{cus}.AsQueryable();
var mockSet=new Mock();
mockSet.As().Setup(m=>m.Provider).Returns(customer.Provider);
mockSet.As().Setup(m=>m.Expression)。返回(customer.Expression);
mockSet.As().Setup(m=>m.ElementType).Returns(customer.ElementType);
mockSet.As().Setup(m=>m.GetEnumerator()).Returns(customer.GetEnumerator());
var mockContext=new Mock();
Setup(m=>m.Customers).Returns(mockSet.Object);
var temp=_customerRepository.GetSingle(cus.Id,mockContext.Object);
Assert.AreEqual(临时名称、客户名称);
Assert.AreEqual(临时电子邮件、客户电子邮件);
Assert.AreEqual(临时Id、客户Id);
}
如果调试代码,我会注意到在GetSingle
函数中,调用dbQuery
的IQueryable
保持null
,因此不能在return语句中使用
为什么会这样
但是,如果我在真实的上下文中运行它,它可以正常工作。这是因为在安装程序中,您在模拟上下文上设置了
.Customers
属性,而不是.Set()
函数。根据目前的设置,Moq不知道该怎么办
mockContext.Setup(m => m.Set<Customer>()).Returns(mockSet.Object);
…然后您需要将测试中的方法更新为
IQueryable<Customer> dbQuery = tempContext.Customers;
IQueryable dbQuery=tempContext.Customers;
这是因为在设置中设置了
.Customers
属性,而不是.Set()
函数。根据目前的设置,Moq不知道该怎么办。
IQueryable<Customer> dbQuery = tempContext.Customers;