3.1 Метод doReturn()
А теперь будет магия…
Допустим, ты создал фейковый мок-объект, но ведь нужно чтобы он как-то работал. При вызове определенных методов делалось что-то важное или методы возвращали определенный результат. Что делать?
Библиотека Mockito позволяет добавить мок-объекту нужное поведение.
Если ты хочешь, чтобы при вызове определенного метода, мок-объект вернул определенный результат, то это “правило” можно добавить объекту с помощью кода:
Mockito.doReturn(результат).when(объект).имяМетода();
Видишь, в конце вызова метода имяМетода?
На самом деле никакого вызова тут не происходит. Метод doReturn()
возвращает специальный proxy-объект с помощью которого следит за вызовами методов объекта и, таким образом, идет запись правила.
Еще раз. Это просто такой хитрый способ записать правило, которое нужно добавить к мок-обекту. Нужна определенная сноровка, чтобы правильно интерпретировать такой код в своей голове, когда его видишь. С опытом приходит.
Думаю, нужен конкретный пример. Давайте создадим мок-объект класса ArrayList
и попросим его метод size()
вернуть число 10. Полный вариант кода будет выглядеть так:
@ExtendWith(MockitoExtension.class)
class DoReturnTest {
@Mock
List mockList;
@Test
public void whenMockAnnotation () {
//создаем правило: вернуть 10 при вызове метода size
Mockito.doReturn(10).when(mockList).size();
//тут вызывается метод и вернет 10!!
assertEquals(10, mockList.size());
}
}
Да, этот код будет работать, тест не упадет.
3.2 Метод when()
Есть еще один способ добавить правило поведения к мок-объекту – через вызов метода Mockito.when()
. Выглядит вот так:
Mockito.when(объект.имяМетода()).thenReturn(результат);
Это такой же способ записи правила поведения мок-объекта, как и предыдущий. Сравните:
Mockito.doReturn(результат).when(объект).имяМетода();
Тут происходит абсолютно одно и то же – конструирование нового правила.
Правда первый пример имеет два минуса:
- вызов
объект.имяМетода()
сильно сбивает с толку. - не будет работать, если метод
имяМетода()
возвращаетvoid
.
Ну и давайте запишем полюбившийся нам пример с помощью Mockito.when()
@ExtendWith(MockitoExtension.class)
class WhenTest {
@Mock
List mockList;
@Test
public void whenMockAnnotation() {
//создаем правило: вернуть 10 при вызове метода size
Mockito.when(mockList.size() ).thenReturn(10);
//тут вызывается метод и вернет 10!!
assertEquals(10, mockList.size());
}
}
3.3 Метод doThrow()
Мы разобрались, как сделать так, чтобы метод мок-объекта вернул определенный результат. А как сделать так, чтобы он кинул определенное исключение? Передать его в doReturn()
?
Чтобы метод не вернул, а именно выбросил (throw) исключение, нужно задать правило с помощью метода doThrow()
.
Mockito.doThrow(исключение.class).when(объект).имяМетода();
И сразу второй вариант:
Mockito.when(объект.имяМетода()).thenThrow(исключение.class);
Немного ожидаемо, да?
Ну вот видишь, ты уже начинаешь разбираться. Закрепим примером:
@ExtendWith(MockitoExtension.class)
class DoThrowTest {
@Mock
List mockList;
@Test
public void whenMockAnnotation() {
Mockito.when(mockList.size() ).thenThrow(IllegalStateException.class);
mockList.size(); //тут кинется исключение
}
}
Если нужно выкинуть определенный объект-исключение, то воспользуйся конструкцией вида:
Mockito.doThrow(new Исключение()).when(объект).имяМетода();
Просто передай в метод doThrow()
объект исключения и он будет выброшен во время вызова метода.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ