Stubbing методов, возвращающих тип с bounded wild-cards в Mockito
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
В Mockito, при создании заглушек методов, возвращающих значения типов с ограничениями, рекомендуется применять any() вместе с приведением типов. Вот пример создания заглушки для метода, который возвращает тип Number
:
import static org.mockito.Mockito.doReturn;
import static org.mockito.ArgumentMatchers.any;
// Создаём мок объекта
YourClass mock = Mockito.mock(YourClass.class);
// Настраиваем заглушку с использованием дженериков
doReturn(42).when(mock).<Number>getNumber(any());
Примечание: Применение объявления типа <Number>
позволяет сохранить безопасность типов при работе с ограничениями, связанными с дженериками.

Детали использования дженериков и заглушек 👨💻
Использование thenAnswer для определения детального поведения
Чтобы точно контролировать поведение заглушки, в частности при использовании дженериков для поддержания безопасности типов, можно использовать thenAnswer:
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
// Создаём мок объекта
YourClass mock = Mockito.mock(YourClass.class);
// Настраиваем заглушку с использованием thenAnswer
when(mock.<List<? extends Number>>getList(any())).thenAnswer(new Answer<List<? extends Number>>() {
@Override
public List<? extends Number> answer(InvocationOnMock invocation) {
// Возвращаем список избранных чисел – все они простые
return new ArrayList<Integer>(Arrays.asList(2, 3, 5, 7, 11));
}
});
Соблюдение безопасности типов при создании заглушек
При создании заглушек всегда желательно использовать подход thenAnswer для обеспечения безопасности типов. Однако в критических ситуациях возможно использование doReturn:
// Создание заглушки в стиле BDD
BDDMockito.willReturn(someList).given(mock).<List<? extends Sporty>>getSportySocks(any());
Особенности doReturn
Метод doReturn
, игнорирующий проверку типов, звучит рискованно. Однако doReturn может оказаться полезным при работе с вайлдкардами, несмотря на утрату безопасности типов:
import static org.mockito.Mockito.doReturn;
// Использование doReturn с вайлдкардом
doReturn(new ArrayList<String>()).when(mock).getList();
Визуализация
Рассмотрим аналогию между использованием методов с ограниченными вайлдкардами в Mockito и выбором пары носков:
Выбираем пару носков:
| Носки | Ограничения |
| ----------------------------- | --------------------- |
| Носки с вайлдкардом `<?>` | Любые носки 🔓 |
| Спортивные носки `<? extends Sporty>` | Только спортивные 🏃♂️ |
Это можно сравнить со следующими методами:
| Вызов метода | Ответ мока |
| ------------------------------------ | --------------------------- |
| getAnkleSock() | Возврат любых носков 🧦 |
| getRunningSock() | Возврат спортивных носков 🏃♀️ |
Создание заглушек с использованием сложных дженериков и thenAnswer
Методы, возвращающие списки с ограниченной типизацией, тоже могут быть задействованы с помощью thenAnswer:
import static org.mockito.Mockito.when;
// Заглушка для метода, возвращающего список
when(mock.<List<? extends Number>>getNumbers()).thenAnswer((Answer<List<Integer>>) invocation -> Arrays.asList(1, 2, 3));
Поддержка сообщества
Познать опыт коллег ценно. Для обсуждения сложных вопросов посетите группу Mockito в Google.
Изучение документации
Документация Mockito — это ресурс для начинающих и опытных специалистов, который позволяет освежить знания по работе с моками.
Полезные материалы
- Mockito – mockito-core 5.10.0 javadoc — официальная документация Mockito помогает разобраться в особенностях работы с заделами.
- java – Когда использовать дженерики, а когда подстановочные символы? – Stack Overflow — обсуждение принципов использования дженериков и вайлдкардов на Stack Overflow.
- Подстановочные символы (Учебные материалы Java) — официальный учебник Oracle по работе с вайлдкардами.
- GitHub – mockito/mockito: Популярная библиотека для создания моков — исходный код Mockito на GitHub, отлично подходит для практического изучения.
- AngelikaLanger.com – Часто задаваемые вопросы о Java Generics — подробный ответ на вопросы о дженериках, включая работу с вайлдкардами.
- Параметры типа с ограничениями (Учебные материалы Java) — учебник по использованию параметризованных типов с ограничениями в Java.