Mockito’s Mock Methods – Mockito’的模拟方法

最后修改: 2016年 5月 4日

1. Overview

1.概述

In this tutorial, we’ll illustrate the various uses of the standard static mock methods of the Mockito API.

在本教程中,我们将说明Mockito API的标准静态mock方法的各种用途。

As in other articles focused on the Mockito framework (like Mockito Verify or Mockito When/Then), the MyList class shown below will be used as the collaborator to be mocked in test cases:

正如在其他关注Mockito框架的文章中(如Mockito VerifyMockito When/Then),下面所示的MyList类将被用作测试案例中被模拟的协作器。

public class MyList extends AbstractList<String> {
    @Override
    public String get(int index) {
        return null;
    }

    @Override
    public int size() {
        return 1;
    }
}

2. Simple Mocking

2.简单的嘲弄

The simplest overloaded variant of the mock method is the one with a single parameter for the class to be mocked:

mock方法的最简单的重载变体是有一个被模拟的类的单一参数的方法。

public static <T> T mock(Class<T> classToMock)

We’ll use this method to mock a class and set an expectation:

我们将使用这个方法来模拟一个类并设置一个期望值。

MyList listMock = mock(MyList.class);
when(listMock.add(anyString())).thenReturn(false);

Then we’ll execute a method on the mock:

然后,我们将在mock上执行一个方法。

boolean added = listMock.add(randomAlphabetic(6));

The following code confirms that we invoked the add method on the mock. The invocation returns a value that matches the expectation we set before:

下面的代码证实了我们调用了mock上的add方法。该调用返回一个与我们之前设定的期望值相匹配的值。

verify(listMock).add(anyString());
assertThat(added).isFalse();

3. Mocking With Mock’s Name

3.用莫克的名字嘲弄

In this section, we’ll cover another variant of the mock method, which is provided with an argument specifying the name of the mock:

在本节中,我们将介绍mock方法的另一个变体,它被提供了一个参数,指定了mock的名称。

public static <T> T mock(Class<T> classToMock, String name)

Generally speaking, the name of a mock has nothing to do with the working code. However, it may be helpful in debugging, as we use the mock’s name to track down verification errors.

一般来说,mock的名字与工作代码没有关系。然而,它在调试中可能是有帮助的,因为我们使用模拟的名字来追踪验证错误。

To ensure the exception message thrown from an unsuccessful verification includes the provided name of a mock, we’ll use assertThatThrownBy.
In the following code, we’ll create a mock for the MyList class and name it myMock:

为了确保从不成功的验证中抛出的异常消息包括所提供的模拟名称,我们将使用assertThatThrownBy.

在下面的代码中,我们将为MyList类创建一个mock,并命名为myMock

MyList listMock = mock(MyList.class, "myMock");

Then we’ll set an expectation on a method of the mock and execute it:

然后,我们将在mock的一个方法上设置一个期望并执行它。

when(listMock.add(anyString())).thenReturn(false);
listMock.add(randomAlphabetic(6));

Next, we’ll call the verification inside the assertThatThrownBy and verify the instance of the exception thrown:

接下来,我们将在assertThatThrownBy里面调用验证,并验证抛出的异常实例。

assertThatThrownBy(() -> verify(listMock, times(2)).add(anyString()))
    .isInstanceOf(TooFewActualInvocations.class)

Further, we can also verify the exception’s message that it should contain the information about the mock:

此外,我们还可以验证异常的信息,它应该包含关于模拟的信息。

assertThatThrownBy(() -> verify(listMock, times(2)).add(anyString()))
    .isInstanceOf(TooFewActualInvocations.class)
    .hasMessageContaining("myMock.add");

Here’s the thrown exception’s message:

这里是被抛出的异常的信息。

org.mockito.exceptions.verification.TooLittleActualInvocations:
myMock.add(<any>);
Wanted 2 times:
at com.baeldung.mockito.MockitoMockTest
  .whenUsingMockWithName_thenCorrect(MockitoMockTest.java:...)
but was 1 time:
at com.baeldung.mockito.MockitoMockTest
  .whenUsingMockWithName_thenCorrect(MockitoMockTest.java:...)

As we can see, the exception message includes the mock’s name, which will be useful for finding the failure point in case of an unsuccessful verification.

我们可以看到,异常消息包括模拟的名字,这对于在验证不成功的情况下找到故障点是很有用的。

4. Mocking With Answer

4.用答案嘲弄

Here we’ll demonstrate the use of a mock variant in which we’ll configure the strategy for the mock’s answers to interaction at creation time. This mock method’s signature in the Mockito documentation looks like the following:

这里我们将演示一个mock变体的使用,在这个变体中,我们将在创建时配置模拟的答案与交互的策略。这个mock方法的签名在Mockito文档中看起来像下面这样。

public static <T> T mock(Class<T> classToMock, Answer defaultAnswer)

Let’s start with the definition of an implementation of the Answer interface:

让我们从定义一个Answer接口的实现开始。

class CustomAnswer implements Answer<Boolean> {
    @Override
    public Boolean answer(InvocationOnMock invocation) throws Throwable {
        return false;
    }
}

We’ll use the CustomAnswer class above for the generation of a mock:

我们将使用上面的CustomAnswer类来生成一个mock。

MyList listMock = mock(MyList.class, new CustomAnswer());

If we don’t set an expectation on a method, the default answer, configured by the CustomAnswer type, will come into play. In order to prove this, we’ll skip over the expectation setting step and jump to the method execution:

如果我们不在方法上设置期望,那么由CustomAnswer类型配置的默认答案就会起作用。为了证明这一点,我们将跳过设置期望的步骤,跳到方法的执行。

boolean added = listMock.add(randomAlphabetic(6));

The following verification and assertion confirm that the mock method with an Answer argument worked as expected:

下面的验证和断言证实了带有Answer参数的mock方法按预期工作。

verify(listMock).add(anyString());
assertThat(added).isFalse();

5. Mocking With MockSettings

5.使用MockSettings进行模拟

The final mock method we’ll cover in this article is the variant with a parameter of the MockSettings type. We use this overloaded method to provide a non-standard mock.

本文要介绍的最后一个mock方法是带有MockSettings类型参数的变量。我们使用这个重载方法来提供一个非标准的模拟。

There are several custom settings supported by methods of the MockSettings interface, such as registering a listener for method invocations on the current mock with invocationListeners, configuring serialization with serializable, specifying the instance to spy on with spiedInstance, configuring Mockito to attempt to use a constructor when instantiating a mock with useConstructor, etc.

MockSettings接口的方法支持一些自定义设置,例如用invocationListeners为当前模拟的方法调用注册一个监听器,用serializable配置序列化,用spiedInstance指定要监视的实例,用useConstructor配置Mockito在实例化模拟时尝试使用一个构造器等等。

For convenience, we’ll reuse the CustomAnswer class introduced in the previous section to create a MockSettings implementation that defines a default answer.

为了方便起见,我们将重新使用上一节介绍的CustomAnswer类,以创建一个MockSettings实现,定义一个默认的答案。

A MockSettings object is instantiated by a factory method:

一个MockSettings对象由一个工厂方法实例化。

MockSettings customSettings = withSettings().defaultAnswer(new CustomAnswer());

We’ll use that setting object in the creation of a new mock:

我们将在创建一个新的模拟中使用该设置对象。

MyList listMock = mock(MyList.class, customSettings);

Similar to the preceding section, we’ll invoke the add method of a MyList instance, and verify that the mock method with a MockSettings argument works as expected:

与上一节类似,我们将调用MyList实例的add方法,并验证带有MockSettings参数的mock方法是否如预期般工作。

boolean added = listMock.add(randomAlphabetic(6));
verify(listMock).add(anyString());
assertThat(added).isFalse();

6. Conclusion

6.结论

In this article, we covered the mock method of Mockito in detail. The implementation of these examples and code snippets can be found in a GitHub project.

在这篇文章中,我们详细介绍了Mockito的mock方法。这些例子和代码片段的实现可以在一个GitHub项目中找到。