从最小起订量模拟集获取 IQueryable
Get IQueryable from Moq mockset
我尝试按照 guide 使用 Entity Framework 和 Moq 来模拟我的上下文以测试我的存储库。
我目前在从我的存储库测试我的 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 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);
}
如果我调试代码,我注意到在 GetSingle
函数中调用 dbQuery
的 IQueryable
仍然是 null
,因此不能在 [=31] 中使用=] 语句。
这是为什么?
但是,如果我 运行 它具有真实的上下文,它就可以正常工作。
那是因为在设置中,您在模拟上下文而不是 .Set<Customer>()
函数上设置了 .Customers
属性。根据当前设置,最小起订量不知道如何处理。
mockContext.Setup(m => m.Set<Customer>()).Returns(mockSet.Object);
以上设置现在应该符合当前格式下被测方法的预期行为。
否则如果这是设置...
mockContext.Setup(m => m.Customers).Returns(mockSet.Object);
...那么您需要将被测方法更新为...
IQueryable<Customer> dbQuery = tempContext.Customers;
测试如期进行。
我尝试按照 guide 使用 Entity Framework 和 Moq 来模拟我的上下文以测试我的存储库。
我目前在从我的存储库测试我的 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 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);
}
如果我调试代码,我注意到在 GetSingle
函数中调用 dbQuery
的 IQueryable
仍然是 null
,因此不能在 [=31] 中使用=] 语句。
这是为什么?
但是,如果我 运行 它具有真实的上下文,它就可以正常工作。
那是因为在设置中,您在模拟上下文而不是 .Set<Customer>()
函数上设置了 .Customers
属性。根据当前设置,最小起订量不知道如何处理。
mockContext.Setup(m => m.Set<Customer>()).Returns(mockSet.Object);
以上设置现在应该符合当前格式下被测方法的预期行为。
否则如果这是设置...
mockContext.Setup(m => m.Customers).Returns(mockSet.Object);
...那么您需要将被测方法更新为...
IQueryable<Customer> dbQuery = tempContext.Customers;
测试如期进行。