«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.