从最小起订量模拟集获取 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 函数中调用 dbQueryIQueryable 仍然是 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;

测试如期进行。