验证是否使用 moq 调用 linq 扩展方法

本文关键字:linq 扩展 方法 调用 moq 是否 验证 | 更新日期: 2023-09-27 18:33:45

我有一个这样的方法:

    public IEnumerable<string> GetCompaniesCities()
    {
        return CompanyRepository.All()
                      .OrderBy(c => c.City)
                      .Select(c => c.City.ToUpper())
                      .Distinct().ToList();
    }

如何测试(使用最小起订量)调用OrderBy (c => c.City)Select(c => c.City.ToUpper()Distinct()

我得到了

对非虚拟(可在 VB 中覆盖)成员的无效验证:x => x.All().OrderBy(c => c.City)

注意:这是一个单元测试,而不是集成测试,所以我不会去数据库

验证是否使用 moq 调用 linq 扩展方法

您不会测试正在调用OrderBy,只需测试返回的字符串是否按顺序排序要容易得多。 即,使用 NUnit:

Assert.That(sut.GetCompaniesCities(), Is.Ordered);

同样,使用 Moq,您无法测试是否调用了像 OrderBy 这样的扩展方法,这是不可能的。


为了解决你关于无法访问数据库的评论,您是对的,模拟您的依赖项消除了访问数据库的需要。但是您可以模拟它们的返回值,以便可以模拟它们确实命中数据库一样。 所以在这里,你的仓库是一个依赖项,你会模拟All()返回一个未排序值的列表:

var companiesUnsorted = new Company[] { 
    new Company { City = "Xyz" },
    new Company { City = "Abc" }
};
var mockRepository = new Mock<ICompanyRepository>();
mockRepository.Setup(p => p.All()).Returns(companiesUnsorted);
var sut = new WhateverClassYourCodeSampleIsFrom(mockRepository.Object);

然后,您只需执行上述断言。

你不能

这样做,仅仅因为moq不能mock扩展方法。这是因为moq使用的是继承,而扩展方法没有继承

您要做的是单元测试中的 CompanyRepository 对象 All 方法的最小起订量。 将 CompanyRepository Moq 注入到包含 GetCompaniesCities() 方法的类中。

然后适当地填充最小起订量,并让单元测试验证 GetCompaniesCities() 方法返回预期结果。 你不关心GetCompaniesCities是如何编码的,只关心它返回正确的值。