Ответ
Mock (Мок-объект) — это тестовый двойник, который имитирует поведение реальной зависимости, позволяя изолировать тестируемый модуль и проверять его взаимодействие с этой зависимостью.
Основное назначение:
- Изоляция: Замена внешних сервисов (БД, API, файловой системы).
- Верификация: Проверка, что тестируемый код корректно вызывает методы зависимости с ожидаемыми аргументами.
- Задание поведения: Определение ответов на вызовы методов (возврат значений, выброс исключений).
Пример с Mockito (Java):
// Зависимость
public class PaymentGateway {
public boolean charge(double amount) { /* ... */ }
}
// Тест
@Test
public void orderService_ShouldChargeCustomer() {
// 1. Создание мока
PaymentGateway mockGateway = Mockito.mock(PaymentGateway.class);
// 2. Задание поведения
Mockito.when(mockGateway.charge(100.0)).thenReturn(true);
// 3. Использование мока в тестируемом сервисе
OrderService service = new OrderService(mockGateway);
boolean success = service.placeOrder(100.0);
// 4. Проверка состояния и взаимодействия
assertTrue(success);
Mockito.verify(mockGateway).charge(100.0); // Верификация вызова
}
Отличие от других тестовых двойников:
- Stub (Заглушка): Пассивный объект, только возвращает предопределённые данные.
- Spy (Шпион): Обёртка над реальным объектом, позволяющая отслеживать вызовы и при необходимости подменять поведение.
- Mock (Мок): Активно используется для верификации взаимодействий.
Ответ 18+ 🔞
А, ну это про моки, блядь! Ну, слушай, сейчас разжуём, как бабушка котлету. Это ж тестовые куклы, которые подсовывают твоему коду вместо настоящих, ебаных, зависимостей.
Представь, ты тестируешь сервис заказа. А он, сука, лезет в базу данных и шлёт запросы в платёжный шлюз. И если этот шлюз сейчас сдох, то все твои тесты накроются медным тазом, а ты будешь сидеть и думать: «Чё за пиздец? Я же просто логику заказа проверяю!». Вот чтобы этого не было, и нужны эти самые моки.
Зачем они, эти мартышлюшки?
- Изоляция, ёпта. Подменяешь реальную базу данных, внешний апишник или файловую систему на послушную куклу. Теперь твой код варится в собственном соку, и ему похуй, что там во внешнем мире творится.
- Верификация, блядь. Это главная фишка! Ты не только подменяешь поведение, но и потом можешь проверить: «А вызывал ли мой сервис метод
charge(100.0)у платёжки? И ровно один раз? И с правильной суммой?». Если не вызывал — значит, логика говно, и тест упадёт. - Задание поведения. Говоришь моку: «Слушай сюда, когда у тебя вызовут метод
findById(5), верни вот этот объект пользователя. А когда вызовутfindById(999), кинь исключениеNotFoundException, нахуй». И он послушно будет это делать.
Смотри, как это выглядит в коде (на примере Mockito, это как стандарт де-факто):
// Вот наша реальная зависимость, которую мы будем мокать
public class PaymentGateway {
public boolean charge(double amount) { /* ...ходит в интернет, общается с банком... */ }
}
// А вот сам тест
@Test
public void orderService_ShouldChargeCustomer() {
// 1. Создаём мок. Вот он, наш актёр на замену.
PaymentGateway mockGateway = Mockito.mock(PaymentGateway.class);
// 2. Задаём ему сценарий. Говорим: «Чувак, если тебя попросят зарядить ровно сотню, ты верни `true`».
Mockito.when(mockGateway.charge(100.0)).thenReturn(true);
// 3. Подсовываем эту подставу в наш сервис и запускаем логику.
OrderService service = new OrderService(mockGateway);
boolean success = service.placeOrder(100.0);
// 4. А теперь — самое интересное! Проверяем и результат, и факт общения.
assertTrue(success); // Стандартная проверка состояния
Mockito.verify(mockGateway).charge(100.0); // А это верификация! «Докажи, что метод charge(100.0) был вызван!»
}
Чем мок отличается от других подставных уродов?
- Stub (Заглушка): Это тупой, блядь, болван. Его задача — просто молча вернуть то, что ты попросил. Он не следит ни за чем. Как бутылка с запиской.
- Spy (Шпион): Это уже хитрая жопа. Обычно это обёртка над реальным объектом. Ты даёшь ему работать по-настоящему, но при этом можешь подсматривать, какие методы вызывались, и влезать, чтобы подменить поведение в отдельных местах. Настоящий стукач.
- Mock (Мок): А это — главный провокатор. Его основная работа — следить за взаимодействием и яростно докладывать тебе, если что-то пошло не по сценарию. «Ага! Ты обещал вызвать
save()два раза, а вызвал один! Пидор несчастный!».
Короче, моки — это твои глаза и уши внутри теста, которые следят, чтобы код не просто работал, но и правильно общался с окружающим миром. Без них — как без рук, только в мире юнит-тестов.