Какие основные возможности предоставляет фреймворк Mockito?

Ответ

Mockito — это фреймворк для создания мок-объектов (mock objects) в unit-тестах, позволяющий изолировать тестируемый класс от его зависимостей.

Ключевые возможности:

  1. Создание моков:

    List<String> mockedList = mock(List.class);
    // Или с аннотацией @Mock и вызовом MockitoAnnotations.openMocks(this)
  2. Задание поведения (stubbing): Определение, что должен возвращать метод мока.

    when(mockedList.get(0)).thenReturn("first");
    when(mockedList.get(anyInt())).thenReturn("element"); // С матчером
    when(mockedList.clear()).thenThrow(new RuntimeException()); // Исключение
  3. Верификация вызовов: Проверка, что методы мока были вызваны с ожидаемыми параметрами.

    verify(mockedList).get(0);
    verify(mockedList, times(2)).add(anyString()); // Проверка количества вызовов
  4. Захват аргументов: Позволяет проверить аргументы, переданные в метод мока.

    ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
    verify(mockedList).add(captor.capture());
    assertEquals("test", captor.getValue());
  5. Spy: Создание частичного мока на основе реального объекта. Вызовы по умолчанию делегируются реальному объекту, но можно переопределить поведение.

    List<String> realList = new ArrayList<>();
    List<String> spiedList = spy(realList);
    doReturn("fake").when(spiedList).get(10); // Заглушка для spy

Почему Mockito популярен: Он предоставляет чистый, читаемый API для создания тестов с моками, что является ключевым для модульного тестирования и соблюдения принципа единой ответственности в тестах.

Ответ 18+ 🔞

Давай разжую тебе про Mockito, чтобы ты не просто тупо зазубрил, а понял, нахуя это вообще нужно. Представь, ты пишешь тест для своего класса, а он там, сука, тянет за собой кучу других классов — базу данных, внешний API, ещё какую-нибудь хрень, которая в тестах не работает или работает как попало. Вот тут-то Mockito и приходит на помощь, как волшебный пендель в задницу всем этим зависимостям.

Что это за зверь? Это библиотека, чтобы создавать подставные объекты (моки). По сути, это куклы, которые притворяются настоящими классами в твоих тестах. Ты сам решаешь, как они будут себя вести, чтобы изолировать свой код и проверить его логику, а не работу соседнего говна.

На что он способен, этот красавчик?

  1. Создание этих самых кукол-моков. Легче лёгкого.

    List<String> подставнойСписок = mock(List.class);
    // Или через аннотацию @Mock, если ты любишь красоту

    Вуаля! Теперь у тебя есть объект List, который нихуя не делает, пока ты ему не прикажешь.

  2. Задаём поведение, или «стаббинг». Это когда ты говоришь моку: «Слушай сюда, когда у тебя вызовут метод get(0), ты возвращай вот эту строку, а не рыпайся куда-то в базу».

    when(подставнойСписок.get(0)).thenReturn("первый");
    when(подставнойСписок.get(anyInt())).thenReturn("какой-то элемент"); // С матчером — умной подставой для аргументов
    when(подставнойСписок.clear()).thenThrow(new RuntimeException()); // А тут, блядь, пусть кинет исключение!

    Ты буквально программируешь реакцию куклы. Хочешь — возвращает значение, хочешь — кидает кирпичом.

  3. Верификация вызовов. Это, блядь, самое важное! Ты же не просто так мок создал. Надо проверить, а вызывался ли вообще твой тестируемый код у этой куклы нужные методы? И с правильными ли аргументами?

    verify(подставнойСписок).get(0); // Проверяем, что get(0) вызывали
    verify(подставнойСписок, times(2)).add(anyString()); // А add() с любой строкой вызывали ровно два раза, Карл!

    Если вызовов не было или было не столько — тест упадёт. Вот и вся магия контроля.

  4. Захват аргументов. А это для параноиков (то есть для хороших разработчиков). Хочешь не просто убедиться, что метод вызывали, а посмотреть, ЧТО ИМЕННО ему скормили?

    ArgumentCaptor<String> захватчик = ArgumentCaptor.forClass(String.class);
    verify(подставнойСписок).add(захватчик.capture());
    assertEquals("тест", захватчик.getValue()); // Ага, поймали! Проверяем, что протащили именно "тест"

    Прямо как в шпионском фильме, ебать!

  5. Spy (шпион). А это, сука, особый вид извращения. Берёшь реальный, живой объект и натягиваешь на него шапочку мока. Он в основном работает как настоящий, но ты можешь выборочно переопределить некоторые его методы.

    List<String> реальныйСписок = new ArrayList<>();
    List<String> шпионскийСписок = spy(реальныйСписок); // Обернули реальный объект
    doReturn("фейк").when(шпионскийСписок).get(10); // А вот для get(10) подсовываем заглушку

    Удобно, когда не хочешь мокать весь объект целиком, а только его гнилую часть.

Почему все его так любят? Да потому что он делает тесты чистыми, читаемыми и изолированными, ёпта! Ты перестаёшь зависеть от внешнего мира в своих тестах. Твоя задача — проверить логику своего класса, а не то, как база данных сегодня с похмелья отвечает. Mockito даёт тебе власть над этой кукольной реальностью. И делает это с таким API, который даже после трёх ночей без сна можно понять. Ну, почти.