Mockito 方法

2024 年 08 月 29 日 | 阅读 9 分钟

Mockito 框架提供了多种方法,如 mock()、verify()、when() 等,用于测试 Java 应用程序。使用这些预定义的方法可以使测试变得非常容易。

下面是 Mockito 方法的简要说明

Mockito mock() 方法

它用于创建给定类或接口的 mock 对象。Mockito 包含五个带有不同参数的 **mock()** 方法。当我们没有为 mock 对象分配任何内容时,它们将返回默认值。所有五个方法都执行相同的对象模拟功能。

以下是带有不同参数的 mock() 方法

  • 带有 Class 的 mock() 方法:用于创建具体类或接口的 mock 对象。它接受类名或接口名作为参数。
    语法: <T> mock(Class<T> classToMock)
  • 带有 Answer 的 mock() 方法:用于创建具有特定过程的类或接口的 mock 对象。这是一个高级 mock 方法,可以在处理遗留系统时使用。它除了接受类名或接口名外,还接受 Answer 作为参数。Answer 是预配置的 mock 回答的枚举。
    语法: <T> mock(Class<T> classToMock, Answer defaultAnswer)
  • 带有 MockSettings 的 mock() 方法:用于创建带有某些非标准设置的 mock 对象。它除了类名或接口名外,还接受 MockSettings 作为额外的设置参数。MockSettings 允许使用附加设置创建 mock 对象。
    语法: <T> mock(Class<T> classToMock, MockSettings mockSettings)
  • 带有 ReturnValues 的 mock() 方法:允许创建给定类或接口的 mock 对象。现在,它已被弃用,因为 ReturnValues 已被 Answer 取代。
    语法: <T> mock(Class<T> classToMock, ReturnValues returnValues)
  • 带有 String 的 mock() 方法:用于通过指定 mock 名称来创建 mock 对象。在调试时,命名 mock 对象可能很有帮助,但在大型复杂代码中使用它是一个糟糕的选择。
    语法: <T> mock(Class<T> classToMock, String name)

以下代码片段展示了如何使用 **mock()** 方法

Mockito when() 方法

它支持方法存根。当我们要让 mock 在调用特定方法时返回特定值时,应该使用它。简单来说,“**当**调用 XYZ() 方法时,**则**返回 ABC。”它主要用于存在执行条件的情况。

语法:<T> when(T methodCall)

以下代码片段展示了如何使用 when() 方法

在上面的代码中,**thenReturn()** 最常与 **when()** 方法一起使用。

Mockito verify() 方法

**verify()** 方法用于检查是否调用了某些指定的方法。简单来说,它验证了在测试中发生过的特定行为。它在测试代码的底部使用,以确保已调用定义的那些方法。

Mockito 框架会跟踪所有方法调用及其参数,以便为对象创建 mock。在创建 mock 后,我们可以使用 verify() 方法来验证定义的条件是否满足。这种类型的测试有时称为**行为测试**。它检查方法是否以正确的参数被调用,而不是检查方法调用的结果。

verify() 方法还用于测试调用次数。因此,我们可以使用 **times 方法、at least once 方法**和 **at most 方法**来测试 mock 方法的确切调用次数。

Mockito 类中提供了两种 verify() 方法,如下所示

  • verify() 方法:验证特定行为发生一次。
    语法: <T> verify(T mock)
  • 带有 VerificationMode 的 verify() 方法:验证某些行为是否至少发生一次、精确调用次数,或者从未调用。
    语法: <T> verify(T mock, VerificationMode mode)

Mockito spy() 方法

Mockito 提供了一个部分 mock 对象的方,称为 **spy** 方法。在使用 spy 方法时,存在一个真实对象,并且会创建该真实对象的 spy 或 stub。如果我们不使用 spy 来 stub 一个方法,它将调用真实方法的行为。spy() 方法的主要功能是覆盖真实对象的特定方法。spy() 方法的一个功能是验证特定方法的调用。

Mockito 类中提供了两种 spy() 方法

  • spy() 方法:它创建真实对象的 spy。spy 方法会调用真实方法,除非它们被 stub 了。我们应该谨慎地偶尔使用真实 spy,例如在处理遗留代码时。
    语法: <T> spy(T object)
  • 带有 Class 的 spy() 方法:它根据类而不是对象创建 spy 对象。spy(T object) 方法对于 spy 抽象类特别有用,因为它们无法实例化。
    语法: <T> spy(Class<T> classToSpy)

以下代码片段展示了如何使用 spy() 方法

Mockito reset() 方法

Mockito reset() 方法用于重置 mock 对象。它主要用于处理容器注入的 mock 对象。通常,reset() 方法会导致代码冗长且测试质量差。最好创建新的 mock 对象而不是使用 reset() 方法。这就是为什么 reset() 方法在测试中很少使用的原因。

reset() 方法的签名是

Mockito verifyNoMoreInteractions() 方法

它用于检查给定的 mock 对象是否有任何未经验证的交互。我们可以在验证完所有 mock 对象后使用此方法,以确保没有其他对象被调用。它还可以检测在测试方法之前发生的未经验证的调用,例如在 setup()、@Before 方法或构造函数中。这是一个可选方法,我们不必在每个测试中都使用它。

verifyNoMoreInteractions() 方法的签名是

Mockito verifyZeroInteractions() 方法

它验证在给定的 mock 对象上没有发生任何交互。它还可以检测在测试方法之前发生的调用,例如在 setup()、@Before 方法或构造函数中。

verifyZeroInteractions() 方法的签名是

Mockito doThrow() 方法

当需要 stub void 方法抛出异常时使用。它为每次方法调用创建一个新的异常实例。Mockito 类中有两种 doThrow() 方法,带有不同的参数,如下所示

  • 带有 Throwable 的 doThrow() 方法:当我们需要用异常 stub void 方法时使用。**语法:** doThrow(Throwable toBeThrown)
    doThrow() 方法的签名是
  • 带有 Class 的 doThrow() 方法:当我们需要用指定类的异常 stub void 方法时使用。
    语法: doThrow(Class<? extends Throwable> toBeThrown)
    doThrow() 方法的签名是

Mockito doCallRealMethod() 方法

当我们需要调用方法的真实实现时使用。换句话说,它用于创建对象的局部 mock。它在很少的情况下使用,例如,用于调用真实方法。它与 spy() 方法类似,唯一的区别是它会导致代码复杂。

doCallRealMethod() 方法的签名是

Mockito doAnswer() 方法

当我们需要用泛型 Answer 类型 stub void 方法时使用。doAnswer() 方法的签名是

Mockito doNothing() 方法

用于将 void 方法设置为 doNothing()。doNothing() 方法很少使用。默认情况下,mock 实例上的 void 方法什么也不做,即不执行任何任务。

doNothing() 方法的签名是

Mockito doReturn() 方法

在无法使用 Mockito.when(object) 的那些罕见情况下使用。始终建议使用 Mockito.when(object) 方法进行 stub,因为它比 doReturn() 方法更安全且更具可读性。

doReturn() 方法的签名是

Mockito inOrder() 方法

它用于创建允许按特定顺序验证 mock 的对象。按顺序验证更加灵活,因为我们不必验证所有交互。我们只需要验证我们有兴趣测试的那些交互(按顺序)。我们还可以使用 inOrder() 方法来创建传递与顺序验证相关的 mock 的 inOrder 对象。

Mockito.inOrder() 方法的签名是

Mockito ignoreStubs() 方法

它用于在验证时忽略给定 mock 的 stubbed 方法。它在 verifyNoMoreInteractions() 或 inOrder() 验证方法中很有用。它还有助于避免冗余的 stubbed 调用验证。

ignoreStubs() 方法的签名是

Mockito times() 方法

它用于验证方法调用的确切次数,这意味着它声明了一个方法被调用了多少次。times() 方法的签名是

Mockito never() 方法

它用于验证交互从未发生过。never() 方法的签名是

Mockito atLeastOnce() 方法

它用于验证至少调用一次,这意味着该方法应该被调用至少一次。

atLeastOnce() 方法的签名是

Mockito atLeast() 方法

它用于验证至少调用 x 次。例如,given atLeast(3) 意味着该方法将调用至少三次。

atLeast() 方法的签名是

Mockito atMost() 方法

它用于验证最多调用 x 次。例如,given atMost(3) 意味着该方法将调用最多三次。

atMost() 方法的签名是

Mockito calls() 方法

它允许在顺序验证中进行非贪婪验证。它只能与 inOrder() 验证方法一起使用。例如,inOrder.verify(mock, calls(3)).xyzMethod("...");

calls() 方法的签名是

Mockito only() 方法

它检查给定的方法是唯一被调用的方法。only() 方法的签名是

Mockito timeout() 方法

它允许 Mockito 执行带有超时的验证。它指示 verify 等待特定时间段以进行特定交互,而不是立即失败。这可能有助于在现有环境中进行测试。

timeout() 方法与 after() 方法不同,因为 after() 方法会等待整个周期,直到最终结果确定,而 timeout() 方法将在验证通过后立即停止。它在测试中很少使用。

timeout() 方法的签名是

Mockito after() 方法

它允许 Mockito 在给定的时间内进行验证。我们已经讨论过 after() 方法与 timeout() 方法不同。

after() 方法的签名是

Mockito validateMockitoUsage() 方法

它用于显式验证框架状态,以检测 Mockito 框架的无效使用。它是 Mockito 的可选功能,因为它一直验证使用情况。内置的 runner (MockitoJUnitRunner) 和 rule (MockitoRule) 都会在每个测试方法后调用 validateMockitoUsage() 方法。

validateMockitoUsage() 方法的签名是

Mockito withSettings() 方法

它用于创建带有额外 mock 设置的 mock 对象。它应该偶尔用于测试。与其使用 withSettings() 方法,不如使用简单的 mock 创建简单的测试。使用 MockSettings 的主要原因如下

  • 通过使用 MockSetting,我们可以轻松地在需要时添加其他 mock 设置。
  • 它将不同的 mock 设置组合在一起,而不会弄乱代码。

withSettings() 方法的签名是