【问题标题】:Automated tests: mocking vs creating test object graph ( using IoC container), what is better under what conditions?自动化测试:模拟与创建测试对象图(使用 IoC 容器),什么条件下更好?
【发布时间】:2025-11-30 08:30:01
【问题描述】:

你如何决定选择什么:

  1. 使用模拟对象进行测试或
  2. 使用 IoC 框架创建测试对象/对象图并对该数据运行测试

【问题讨论】:

    标签: unit-testing inversion-of-control mocking automated-tests


    【解决方案1】:

    这取决于您要测试的内容。模拟出协作者的单元测试很棒,因为

    • 他们真的非常快
    • 它们小巧易懂
    • 它们不依赖于更广阔的世界,这使得它们易于运行
    • 它们提供出色的缺陷定位

    但是,纯单元测试无法告诉您是否在 IoC 容器中正确配置了对象,数据库连接字符串是否有效等。您需要一个运行 IoC 容器并真正联系到 Db 的测试来证明这些东西。

    如果您尽可能多地编写纯独立的单元测试,那么您的构建将保持快速。这是至关重要的,因为一个缓慢的 bulid 运行得更少。即便如此,不要忘记添加一些有线测试来证明您的应用程序“挂在一起”。

    例如,我们对容器中的每个服务都有一个(单一)测试,以证明我们可以从 IoC 容器请求它。这证明我们已经连接好,从那时起它一直是单元测试。我们有很多纯单元测试。

    然后将全部内容包含在一些应用程序级别的功能测试中,以证明应用程序本身可以满足用户的需求。

    要记住的是每种测试类型的时间成本。从纯单元 -> 有线 -> 功能测试在中断时会花费一个数量级的执行时间和复杂性。

    【讨论】:

      【解决方案2】:

      我对在我的大部分应用程序中使用 IoC 感到非常满意,尤其是我很欣赏可以注入测试数据源进行测试。

      对于更多有问题的后端连接(当前是单个 ESB 调用)或需要复杂状态的函数,我会模拟。

      【讨论】:

        【解决方案3】:

        对于单元测试:如果一个对象不是被测试的对象,则模拟或存根它。 这样你就可以直接控制它,让它返回你想要的数据。

        如果您创建一个测试对象/对象图,您必须对其进行设置,以便它提供您想要的数据。这可能比您想要的要多得多。

        对于集成测试,您当然要一次测试整个对象图。

        【讨论】:

          【解决方案4】:

          如果您需要编写大量初始化代码 - 模拟框架可能会帮助您编写更好、更易于理解的单元测试。

          无需重新编写模拟框架可以拯救您的代码。

          【讨论】: