«1. Обзор

В этом руководстве показаны различные варианты использования стандартных статических фиктивных методов Mockito API.

Как и в других статьях, посвященных фреймворку Mockito (например, Mockito Verify или Mockito When/Then), класс MyList, показанный ниже, будет использоваться в качестве соавтора, который будет имитироваться в тестовых примерах:

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

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

2. Простой Имитация

Простейший перегруженный вариант mock-метода — это вариант с одним параметром для имитируемого класса:

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

Мы будем использовать этот метод, чтобы имитировать класс и установить ожидание:

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

~ ~~ Затем выполните метод на макете:

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

Следующий код подтверждает, что метод добавления был вызван на макете и что вызов возвращает значение, которое соответствует ожиданиям, которые мы установили ранее:

verify(listMock).add(anyString());
assertThat(added, is(false));

~ ~~ 3. Мокинг с именем мока

В этом разделе мы рассмотрим другой вариант метода mock, который предоставляется с аргументом, указывающим имя макета:

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

Вообще говоря, имя mock не имеет ничего общего с рабочим кодом, но может быть полезен, когда дело доходит до отладки, когда имя mock используется для отслеживания проверки. рорс.

Чтобы убедиться, что предоставленное имя макета включено в сообщение об исключении, вызванном неудачной проверкой, мы будем полагаться на реализацию JUnit интерфейса TestRule с именем ExpectedException и включим его в тестовый класс:

@Rule
public ExpectedException thrown = ExpectedException.none();

Это правило будет использоваться для обработки исключений, вызванных тестовыми методами.

В следующем коде мы создаем макет для класса MyList и называем его myMock:

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

Затем устанавливаем ожидание для метода макета и выполняем его:

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

Мы создать преднамеренно неудачную проверку, которая должна вызвать исключение с сообщением, содержащим информацию о макете. Для этого необходимо сначала установить ожидания для исключения:

thrown.expect(TooLittleActualInvocations.class);
thrown.expectMessage(containsString("myMock.add"));

Следующая проверка должна завершиться ошибкой и выдать исключение, соответствующее ожидаемому:

verify(listMock, times(2)).add(anyString());

Вот сообщение о выброшенном исключении: ~ ~~

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:...)

Как мы видим, имя мока было включено в сообщение об исключении, которое будет полезно для поиска точки отказа в случае неудачной проверки.

4. Насмешка с ответом

Здесь мы продемонстрируем использование варианта макета, в котором стратегия ответов макета на взаимодействие настраивается во время создания. Сигнатура этого фиктивного метода в документации Mockito выглядит следующим образом:

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

Давайте начнем с определения реализации интерфейса Answer:

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

Приведенный выше класс CustomAnswer используется для создания фиктивного :

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

Если мы не установим ожидание для метода, в игру вступит ответ по умолчанию, настроенный типом CustomAnswer. Чтобы доказать это, мы пропустим шаг настройки ожидания и перейдем к выполнению метода:

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

Следующая проверка и утверждение подтверждают, что фиктивный метод с аргументом ответа работал должным образом:

verify(listMock).add(anyString());
assertThat(added, is(false));

~ ~~ 5. Мокирование с помощью MockSettings

Последний мок-метод, который рассматривается в этой статье, — это вариант с параметром типа MockSettings. Этот перегруженный метод используется для предоставления нестандартного макета.

Существует несколько пользовательских настроек, которые поддерживаются методами интерфейса MockSettings, например, регистрация прослушивателя для вызовов методов в текущем макете с помощью invocationListeners, настройка сериализации с помощью сериализуемого, указание экземпляра для слежения с помощью spiedInstance, настройка Mockito для попытаться использовать конструктор при создании макета с помощью useConstructor и некоторых других.

Для удобства мы будем повторно использовать класс CustomAnswer, представленный в предыдущем разделе, для создания реализации MockSettings, определяющей ответ по умолчанию.

Объект MockSettings создается фабричным методом следующим образом:

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

Этот объект настроек будет использоваться при создании нового макета:

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

«

boolean added = listMock.add(randomAlphabetic(6));
verify(listMock).add(anyString());
assertThat(added, is(false));

«Как и в предыдущем разделе, мы вызовем метод add экземпляра MyList и убедимся, что фиктивный метод с аргументом MockSettings работает должным образом, используя следующий фрагмент кода:

6. Заключение ~~ ~ В этом руководстве подробно рассматривается фиктивный метод Mockito. Реализацию этих примеров и фрагментов кода можно найти в проекте GitHub.