Ответ
Mockito — это фреймворк для создания мок-объектов (mock objects) в unit-тестах, позволяющий изолировать тестируемый класс от его зависимостей.
Ключевые возможности:
-
Создание моков:
List<String> mockedList = mock(List.class); // Или с аннотацией @Mock и вызовом MockitoAnnotations.openMocks(this) -
Задание поведения (stubbing): Определение, что должен возвращать метод мока.
when(mockedList.get(0)).thenReturn("first"); when(mockedList.get(anyInt())).thenReturn("element"); // С матчером when(mockedList.clear()).thenThrow(new RuntimeException()); // Исключение -
Верификация вызовов: Проверка, что методы мока были вызваны с ожидаемыми параметрами.
verify(mockedList).get(0); verify(mockedList, times(2)).add(anyString()); // Проверка количества вызовов -
Захват аргументов: Позволяет проверить аргументы, переданные в метод мока.
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); verify(mockedList).add(captor.capture()); assertEquals("test", captor.getValue()); -
Spy: Создание частичного мока на основе реального объекта. Вызовы по умолчанию делегируются реальному объекту, но можно переопределить поведение.
List<String> realList = new ArrayList<>(); List<String> spiedList = spy(realList); doReturn("fake").when(spiedList).get(10); // Заглушка для spy
Почему Mockito популярен: Он предоставляет чистый, читаемый API для создания тестов с моками, что является ключевым для модульного тестирования и соблюдения принципа единой ответственности в тестах.
Ответ 18+ 🔞
Давай разжую тебе про Mockito, чтобы ты не просто тупо зазубрил, а понял, нахуя это вообще нужно. Представь, ты пишешь тест для своего класса, а он там, сука, тянет за собой кучу других классов — базу данных, внешний API, ещё какую-нибудь хрень, которая в тестах не работает или работает как попало. Вот тут-то Mockito и приходит на помощь, как волшебный пендель в задницу всем этим зависимостям.
Что это за зверь? Это библиотека, чтобы создавать подставные объекты (моки). По сути, это куклы, которые притворяются настоящими классами в твоих тестах. Ты сам решаешь, как они будут себя вести, чтобы изолировать свой код и проверить его логику, а не работу соседнего говна.
На что он способен, этот красавчик?
-
Создание этих самых кукол-моков. Легче лёгкого.
List<String> подставнойСписок = mock(List.class); // Или через аннотацию @Mock, если ты любишь красотуВуаля! Теперь у тебя есть объект
List, который нихуя не делает, пока ты ему не прикажешь. -
Задаём поведение, или «стаббинг». Это когда ты говоришь моку: «Слушай сюда, когда у тебя вызовут метод
get(0), ты возвращай вот эту строку, а не рыпайся куда-то в базу».when(подставнойСписок.get(0)).thenReturn("первый"); when(подставнойСписок.get(anyInt())).thenReturn("какой-то элемент"); // С матчером — умной подставой для аргументов when(подставнойСписок.clear()).thenThrow(new RuntimeException()); // А тут, блядь, пусть кинет исключение!Ты буквально программируешь реакцию куклы. Хочешь — возвращает значение, хочешь — кидает кирпичом.
-
Верификация вызовов. Это, блядь, самое важное! Ты же не просто так мок создал. Надо проверить, а вызывался ли вообще твой тестируемый код у этой куклы нужные методы? И с правильными ли аргументами?
verify(подставнойСписок).get(0); // Проверяем, что get(0) вызывали verify(подставнойСписок, times(2)).add(anyString()); // А add() с любой строкой вызывали ровно два раза, Карл!Если вызовов не было или было не столько — тест упадёт. Вот и вся магия контроля.
-
Захват аргументов. А это для параноиков (то есть для хороших разработчиков). Хочешь не просто убедиться, что метод вызывали, а посмотреть, ЧТО ИМЕННО ему скормили?
ArgumentCaptor<String> захватчик = ArgumentCaptor.forClass(String.class); verify(подставнойСписок).add(захватчик.capture()); assertEquals("тест", захватчик.getValue()); // Ага, поймали! Проверяем, что протащили именно "тест"Прямо как в шпионском фильме, ебать!
-
Spy (шпион). А это, сука, особый вид извращения. Берёшь реальный, живой объект и натягиваешь на него шапочку мока. Он в основном работает как настоящий, но ты можешь выборочно переопределить некоторые его методы.
List<String> реальныйСписок = new ArrayList<>(); List<String> шпионскийСписок = spy(реальныйСписок); // Обернули реальный объект doReturn("фейк").when(шпионскийСписок).get(10); // А вот для get(10) подсовываем заглушкуУдобно, когда не хочешь мокать весь объект целиком, а только его гнилую часть.
Почему все его так любят? Да потому что он делает тесты чистыми, читаемыми и изолированными, ёпта! Ты перестаёшь зависеть от внешнего мира в своих тестах. Твоя задача — проверить логику своего класса, а не то, как база данных сегодня с похмелья отвечает. Mockito даёт тебе власть над этой кукольной реальностью. И делает это с таким API, который даже после трёх ночей без сна можно понять. Ну, почти.