Mock vs. Stub vs. Spy(模拟、存根和间谍)

2024 年 8 月 29 日 | 阅读 3 分钟

Mock (模拟)

Mocks 是存储方法调用的对象。它被称为用于测试中使用的依赖项的动态包装器。它用于记录和验证 Java 类之间的交互。mock 被称为测试替身中最强大和最灵活的版本。我们使用一个叫做 mock() 的方法进行模拟。

使用 mocks 的主要功能是它可以完全控制模拟对象的行为。模拟对象通常用于 行为验证。 行为一词是指检查应用于对象的正确方法和路径。

Mocks 主要通过使用库或模拟框架(如 Mockito、JMock 和 EasyMock)创建。它用于测试大量的测试套件,其中存根是不够的。mock 的一个重要功能是,我们可以验证给定方法被调用的次数。

以下代码片段显示了如何使用 mock()。

存根 (Stub)

Stubs(存根)是保存预定义数据并使用它在测试期间给出响应的对象。换句话说,存根是一个对象,它类似于一个真实的对象,具有测试所需的最少数量的方法。当我们不想使用会使用真实数据给出响应的对象时,会使用存根。存根被称为最轻量级,也是测试替身中最静态的版本。

Stubs 的主要功能是

  • 它总是返回预定义的输出,而与输入无关。
  • 它可用于类似于数据库对象。
  • Stubs 用于减少创建真实对象期间出现的复杂性。它们主要用于执行 状态验证

Spy (间谍)

Spies(间谍)被称为 部分模拟对象。这意味着 spy 创建真实对象的局部对象或半个虚拟对象,通过存根或监视真实对象。 在监视中,真实对象保持不变,我们只监视它的一些特定方法。 换句话说,我们获取现有的(真实的)对象并 替换监视 它的某些方法。

当一个类有很多方法,并且我们想模拟某些方法时,间谍很有用。 在这种情况下,我们应该优先使用间谍而不是模拟和存根。 如果方法没有被存根,它会调用真实的方法行为。

在 Mockito 中,使用 spy() 方法创建间谍对象。 它允许我们调用真实对象的正常方法。 以下代码片段显示了如何使用 spy() 方法。

Stub(存根)和 Mock(模拟)的区别

参数存根 (Stub)Mock (模拟)
数据源存根的数据源是硬编码的。它通常与测试套件紧密耦合。模拟上的数据由测试设置。
创建者Stubs 通常是手写的,有些是由工具生成的。Mocks 通常使用第三方库创建,例如 Mockito、JMock 和 WireMock。
用途Stubs 主要用于简单的测试套件。Mocks 主要用于大型测试套件。
图形用户界面 (GUI)Stubs 没有 GUI。Mocks 有 GUI。

以下是模拟和间谍的一些区别

参数Mock (模拟)Spy (间谍)
用途Mocks 用于创建完全模拟或虚拟对象。 它主要用于大型测试套件。Spies 用于创建部分或半模拟对象。 像模拟一样,间谍也用于大型测试套件。
默认行为使用模拟对象时,方法(未存根时)的默认行为是无操作(不执行任何操作。)使用间谍对象时,方法的默认行为(未存根时)是真实的方法行为。

在之前的教程中,我们讨论了一些存根、模拟和监视的例子。 为了更好地理解存根、模拟和监视之间的区别,请查看这些例子。