【问题标题】:Injecting Mocks on large dependency object graph在大型依赖对象图上注入 Mocks
【发布时间】:2011-11-02 15:52:39
【问题描述】:

对于我要测试的对象,我有一个相当重要的依赖关系图。解决我的依赖关系而不必到处注册模拟的最简单方法是什么?

例如,我有一个这样的依赖图:

  PublicApi
    ApiService
      AccountingFacade
         BillingService
           BillingValidation
           BillingRepository
         UserService
           UserRepository

我想测试PublicApi.CreateUser(),我希望它运行所有代码,但我想模拟存储库,因此我不必向数据库写入任何内容。我应该只使用 DI 容器并注册我的所有服务,用模拟替换存储库,然后解析 PublicApi 并运行该方法吗?

我正在研究 AutoFixture,它看起来可能能够处理这样的事情,但我无法完全理解整个“冻结”与“注册”以及它与 Moq 的集成。

【问题讨论】:

    标签: c# unit-testing dependency-injection moq autofixture


    【解决方案1】:

    对于单元测试,您应该只模拟直接依赖项。在您的情况下,您创建PublicApi 并为ApiService 注入一个模拟,并验证PublicApi 是否在ApiService 模拟上调用具有正确值的适当方法。

    以同样的方式测试与更深层次的依赖关系隔离的所有其他组件。

    如果您想测试多个组件的组合,那不是单元测试,而是集成测试。因此,这取决于您如何将课程组合在一起。例如如果您使用的是 IoC 容器,它可能支持以某种方式替换存储库的配置。在这种情况下,您可以使用应用程序的配置并将存储库以及可能的视图替换为模拟。

    【讨论】:

    • 这是有道理的。我可以通过多层测试获得全面覆盖,而不是一次测试多层。
    • 没错,它使测试本身变得更加简单和易于理解。
    【解决方案2】:

    这可能一点用都没有,但我还是会说出来。

    您似乎一次尝试测试太多,为什么不测试 BillingService -> BillingValidation,然后是 BillingService -> BillingRepository 等。这样您将拥有一套测试证明每个测试都有效,然后当您在 PublicApi 层上,您只需要模拟 ApiService,因为您已经测试了它下面的所有内容,因此再次测试它没有任何价值。

    通常我一次只会测试 1 层,但我不知道你的完整场景,所以你可能有一些我没有考虑到的东西,所以如果是这种情况,你真的需要一起测试所有这些我只会引入一个简单轻量级的 DI 框架,比如 Ninject 之类的。

    这样,您可以将所有类型绑定到模拟,然后从中实例化您的 PublicApi。

    使用 ninject 它看起来像:

    Kernel.Bind<UserRepository>.ToConst(YourMockUserRepositoryInstance);
    Kernel.Bind<UserService>.ToConst(YourMockUserServiceInstance);
    Kernel.Bind<BillingRepository>.ToConst(YourMockBillingRepositoryInstance);
    Kernel.Bind<BillingValidation>.ToConst(YourMockBillingValidationInstance);
    Kernel.Bind<BillingService>.ToConst(YourMockBillingServiceInstance);
    Kernel.Bind<AccountingFacade>.ToConst(YourMockAccountingFacadeInstance);
    Kernel.Bind<ApiService>.ToConst(YourMockApiServiceInstance);
    Kernel.Bind<PublicApi>.ToSelf();
    
    var publicApi = Kernel.Get<PublicApi>();
    

    虽然你必须问自己,你在这里测试什么?如果它只是互动,我会像我第一次提到的那样做,如果它更多,那么可能会考虑后一种选择。不管怎样,我希望它能给你一些选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-03
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 2021-08-04
      • 2023-03-20
      • 2016-02-11
      • 2012-09-23
      相关资源
      最近更新 更多