Ответ
Mockito — это библиотека для модульного тестирования в Java, которая создает mock-объекты (заглушки) для замены реальных зависимостей. Это позволяет изолировать тестируемый код и проверять его взаимодействие с другими объектами.
Основные концепции и API:
-
Создание мока:
List<String> mockedList = Mockito.mock(List.class);Или с использованием аннотаций (требует
MockitoAnnotations.openMocks(this)или@ExtendWith(MockitoExtension.class)в JUnit 5):@Mock List<String> mockedList; -
Задание поведения (stubbing):
when(mockedList.get(0)).thenReturn("first"); when(mockedList.get(anyInt())).thenThrow(new RuntimeException()); -
Проверка вызовов (verification):
verify(mockedList).get(0); // Проверяет, что метод был вызван 1 раз verify(mockedList, times(2)).add(anyString()); // Проверяет точное количество вызовов verify(mockedList, never()).clear(); // Проверяет, что метод не вызывался -
Аргументные матчеры:
any(),eq(),contains()и др. для гибкой проверки аргументов.
Пример полного теста:
@ExtendWith(MockitoExtension.class)
class ServiceTest {
@Mock
private DependencyRepository repository;
@InjectMocks
private ServiceUnderTest service;
@Test
void testServiceCall() {
// Задаем поведение мока
when(repository.findById(1L)).thenReturn(new Entity("test"));
// Вызываем тестируемый метод
String result = service.process(1L);
// Проверяем результат и взаимодействие
assertEquals("processed: test", result);
verify(repository).findById(1L);
}
}
Spy vs Mock: @Spy создает частичный мок на реальном объекте, позволяя вызывать реальные методы, если их поведение не переопределено.
Ответ 18+ 🔞
Ну, смотри, есть такая штука — Mockito. Это, блядь, библиотека для тестирования в Java, которая умеет создавать эти ваши mock-объекты, то есть, по сути, заглушки. Зачем? А чтобы, сука, отвязаться от реальных зависимостях, которые могут быть медленными, глючными или просто не нужны в конкретном тесте. Изолировал код, который проверяешь, и смотришь, как он общается с другими — вот и вся магия, ёпта.
Основные штуки, которые надо знать:
-
Создание мока: Ну, элементарно, Ватсон. Либо в лоб:
List<String> mockedList = Mockito.mock(List.class);Либо через аннотации, как цивилизованные люди. Только не забудь потом
MockitoAnnotations.openMocks(this)запустить, а в JUnit 5 можно@ExtendWith(MockitoExtension.class)на класс повесить.@Mock List<String> mockedList; -
Задаём поведение (stubbing): Тут всё просто: говоришь моку — «когда с тобой вот это сделают, верни вот это». Или, наоборот, «взбрыкни исключением».
when(mockedList.get(0)).thenReturn("first"); when(mockedList.get(anyInt())).thenThrow(new RuntimeException());Главное — не перепутай порядок, а то будешь потом, как Герасим, метаться и думать: «Что же я, мудак, сделал?».
-
Проверка вызовов (verification): А вот это, блядь, самое важное. Написал код, он что-то там вызвал, а ты должен убедиться, что вызов был, и именно такой, как надо.
verify(mockedList).get(0); // Проверяет, что метод вызвали ровно один раз verify(mockedList, times(2)).add(anyString()); // А тут — что два раза, ни больше, ни меньше verify(mockedList, never()).clear(); // А этот, сука, вообще не должен был трогаться! -
Аргументные матчеры: Это такие хитрожопые штуки вроде
any(),eq(),contains(). Позволяют не забивать голову точными значениями, а проверять по шаблону. Удобно, ебать.
Вот тебе полный пример, чтоб было понятно, как это в кучу собирается:
@ExtendWith(MockitoExtension.class)
class ServiceTest {
@Mock
private DependencyRepository repository; // Заглушка для репозитория
@InjectMocks
private ServiceUnderTest service; // Сюда моки автоматом воткнутся
@Test
void testServiceCall() {
// Говорим заглушке: «Чувак, когда вызовут findById с единичкой — верни вот этот объект»
when(repository.findById(1L)).thenReturn(new Entity("test"));
// А теперь дергаем наш сервис, который внутри должен использовать репозиторий
String result = service.process(1L);
// Сперва проверяем, что результат правильный
assertEquals("processed: test", result);
// А потом — что репозиторий таки дернули ровно один раз с нужным аргументом
verify(repository).findById(1L);
}
}
И ещё про Spy vs Mock: Есть такая аннотация @Spy. Это, блядь, не полная заглушка, а такой полупидор. Создаёшь её на реальном объекте, и он по умолчанию ведёт себя как настоящий. Но если ты ему явно не пропишешь, что делать в конкретном случае — он вызовет реальный метод. Полезно, когда надо замокать только один метод в классе, а остальные оставить живыми. Но осторожно, а то ненароком реальную базу данных дернешь в тесте — будет тебе волнение ебать.