如果 IRepository 调用 return 没有值,则使用 Moq 解决测试依赖关系的目的

The purpose of using Moq to resolve test dependencies if IRepository calls return no values

我是 TDD 的新手,我正在使用一堆 XUnit、AutoFixture 和 Moq。我想知道当您测试调用访问数据库的存储库的函数时,最小起订量的目的是什么。

例如:
我有一个简单的项目结构,其中我的 BLL 引用了我的 DAL。在我的正常应用程序中,IRepository 被注入 ProductBLL.cs。所以我看到 Moq 帮助我在我的测试中注入相同的存储库。 (但是,如果命中数据库的函数不起作用,那又有什么意义呢?)

我的问题:
假设我正在进行测试以测试我的业务层,并且我想测试调用我的存储库的函数,这些存储库在我的实际代码中调用我的数据库。如果使用 Moq 并且没有数据 returned 是否可以测试这样的功能?在下面的示例中 sut.GetProducts() return 什么都没有,在我的实际代码中它访问数据库并执行 return 某些操作。

假设我有一个使用最小起订量执行此操作的简单测试:

    [Fact]
    public void TestGetProducts_Manual_Moq()
    {
        // Arrange
        var mockCustomerRepository = new Mock<IProductRepository>();

        var sut = new ProductBLL(mockProductRepository.Object);

        // Act
        var result = sut.GetProducts();

        // Assert
        Assert.True(result.Count > 0);
    }

这是一个使用 AutoFixture 结合 Moq 的简单测试:(我认为在这个例子中 AutoFixture 至少会 return 3 行虚拟数据)

    [Fact]
    public void TestGetProducts_AutoMoq()
    {
        // Arrange
        Fixture fixture = new Fixture();

        // Add auto mocking support for Moq
        fixture.Customize(new AutoMoqCustomization());

        var sut = fixture.Create<ProductBLL>();

        // Act
        var result = sut.GetProducts();

        // Assert
        Assert.True(result.Count > 0);
    }

如果 GetProducts 只是调用存储库而不对结果进行任何操作,那么是否值得对其进行测试可能值得商榷。但是,通常 GetProducts 可能会做很多其他事情,例如:过滤、分组、更改格式和许多其他事情。

在这种情况下,您可以验证的不仅仅是检查是否 GetProducts returns 某些结果。例如,假设存储库 returns 个类型为 A 的对象,但 GetProducts returns 个类型为 B 的对象。这意味着必须将数据从 A 类型的对象复制到 B 类型的对象。在这种情况下,可以删除一些数据,重新格式化等。您的测试应该验证最终结果是否正确。

其次,GetProducts可以使用存储库的1、2或更多方法。这些方法有的只能使用一次,有的可以使用多次。如果是这样,您可以使用模拟来验证是否使用了方法:

  • 正确的次数
  • 顺序正确
  • 参数值正确

This and this questions are about verifying a correct order of methods calls in Moq. This question is about verifying a number of calls in Moq. I also strongly suggest to read this教程。