ПРИХОДИТЕ УЧИТЬСЯ НОВОЙ ПРОФЕССИИ ЛЕТОМ СО СКИДКОЙ ДО 70%Забронировать скидку

Stubbing методов, возвращающих тип с bounded wild-cards в Mockito

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

В Mockito, при создании заглушек методов, возвращающих значения типов с ограничениями, рекомендуется применять any() вместе с приведением типов. Вот пример создания заглушки для метода, который возвращает тип Number:

Java
Скопировать код
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> позволяет сохранить безопасность типов при работе с ограничениями, связанными с дженериками.

Пройдите тест и узнайте подходит ли вам сфера IT
Пройти тест

Детали использования дженериков и заглушек 👨‍💻

Использование thenAnswer для определения детального поведения

Чтобы точно контролировать поведение заглушки, в частности при использовании дженериков для поддержания безопасности типов, можно использовать thenAnswer:

Java
Скопировать код
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:

Java
Скопировать код
// Создание заглушки в стиле BDD
BDDMockito.willReturn(someList).given(mock).<List<? extends Sporty>>getSportySocks(any());

Особенности doReturn

Метод doReturn, игнорирующий проверку типов, звучит рискованно. Однако doReturn может оказаться полезным при работе с вайлдкардами, несмотря на утрату безопасности типов:

Java
Скопировать код
import static org.mockito.Mockito.doReturn;

// Использование doReturn с вайлдкардом
doReturn(new ArrayList<String>()).when(mock).getList();

Визуализация

Рассмотрим аналогию между использованием методов с ограниченными вайлдкардами в Mockito и выбором пары носков:

Markdown
Скопировать код
Выбираем пару носков:
| Носки                         | Ограничения            |
| ----------------------------- | --------------------- |
| Носки с вайлдкардом `<?>`          | Любые носки 🔓         |
| Спортивные носки `<? extends Sporty>` | Только спортивные 🏃‍♂️ |

Это можно сравнить со следующими методами:
| Вызов метода                         | Ответ мока             |
| ------------------------------------ | --------------------------- |
| getAnkleSock()                       | Возврат любых носков 🧦      |
| getRunningSock()                     | Возврат спортивных носков 🏃‍♀️ |

Создание заглушек с использованием сложных дженериков и thenAnswer

Методы, возвращающие списки с ограниченной типизацией, тоже могут быть задействованы с помощью thenAnswer:

Java
Скопировать код
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 — это ресурс для начинающих и опытных специалистов, который позволяет освежить знания по работе с моками.

Полезные материалы

  1. Mockito – mockito-core 5.10.0 javadoc — официальная документация Mockito помогает разобраться в особенностях работы с заделами.
  2. java – Когда использовать дженерики, а когда подстановочные символы? – Stack Overflow — обсуждение принципов использования дженериков и вайлдкардов на Stack Overflow.
  3. Подстановочные символы (Учебные материалы Java) — официальный учебник Oracle по работе с вайлдкардами.
  4. GitHub – mockito/mockito: Популярная библиотека для создания моков — исходный код Mockito на GitHub, отлично подходит для практического изучения.
  5. AngelikaLanger.com – Часто задаваемые вопросы о Java Generics — подробный ответ на вопросы о дженериках, включая работу с вайлдкардами.
  6. Параметры типа с ограничениями (Учебные материалы Java) — учебник по использованию параметризованных типов с ограничениями в Java.