- Home »

Mockito verify — проверка вызовов методов в юнит-тестах Java
Если ты когда-нибудь писал юнит-тесты на Java, то наверняка сталкивался с ситуацией: нужно проверить, что твой код действительно вызывает нужные методы у зависимостей — и делает это ровно столько раз, сколько надо. Особенно если ты автоматизируешь рутину, связанную с серверным кодом, где важно не только что-то сделать, но и не сделать лишнего. Вот тут и приходит на помощь Mockito с его магическим verify()
. В этой статье разберёмся, как работает Mockito.verify
, зачем он нужен, как быстро его внедрить в проект, и какие подводные камни могут встретиться. Всё на пальцах, с примерами, схемами и лайфхаками для тех, кто ценит время и нервы.
Что такое Mockito verify и зачем он нужен?
Mockito — это библиотека для создания моков (заглушек) в юнит-тестах на Java. Она позволяет подменять реальные зависимости тестируемого класса на “фейковые” объекты, чтобы тестировать только нужную логику, не трогая базы, сети и прочие внешние штуки. verify()
— это способ убедиться, что твой код действительно взаимодействует с этими моками так, как ты задумал. Например, ты хочешь проверить, что метод sendEmail()
вызывается ровно один раз, а не десять, или что метод deleteUser()
вообще не трогается.
- Контроль над побочными эффектами: Проверяешь, что твой сервис не отправляет лишние письма или не удаляет пользователей случайно.
- Документирование поведения: Тесты с
verify()
показывают, как должен работать твой код — это почти как документация, только живая. - Безопасность рефакторинга: Меняешь код — тесты с
verify()
сразу скажут, если ты что-то сломал в логике вызовов.
Как это работает?
Всё просто: ты создаёшь мок (например, EmailService
), передаёшь его в свой класс, вызываешь нужные методы, а потом с помощью verify()
спрашиваешь у Mockito: “А был ли вызван метод sendEmail()
с такими-то параметрами?” Mockito ведёт учёт всех вызовов и честно отвечает.
EmailService emailService = mock(EmailService.class);
UserManager userManager = new UserManager(emailService);
userManager.registerUser("[email protected]");
// Проверяем, что sendEmail был вызван ровно один раз
verify(emailService, times(1)).sendEmail("[email protected]");
Если метод не был вызван, или был вызван не с теми параметрами — тест упадёт. Если был вызван больше/меньше раз — тоже упадёт. Всё строго и прозрачно.
Как быстро и просто всё настроить?
Если у тебя уже есть Maven или Gradle — добавить Mockito проще простого. Вот минимальный набор действий:
- Добавь зависимость в
pom.xml
илиbuild.gradle
- Импортируй статические методы Mockito в тестах
- Создавай моки через
mock()
или@Mock
- Пиши тесты с
verify()
// Maven
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
// Gradle
testImplementation 'org.mockito:mockito-core:5.2.0'
Дальше — дело техники. Вот пример теста:
import static org.mockito.Mockito.*;
@Test
public void testSendEmailCalledOnce() {
EmailService emailService = mock(EmailService.class);
UserManager userManager = new UserManager(emailService);
userManager.registerUser("[email protected]");
verify(emailService, times(1)).sendEmail("[email protected]");
}
Если хочешь меньше бойлерплейта — используй @Mock
и @InjectMocks
с @ExtendWith(MockitoExtension.class)
(JUnit 5) или @RunWith(MockitoJUnitRunner.class)
(JUnit 4).
Примеры, схемы, практические советы
Положительный кейс: всё работает как надо
verify(emailService).sendEmail("[email protected]");
Тест проходит, если sendEmail
был вызван ровно один раз с этим адресом.
Отрицательный кейс: метод не вызван
verify(emailService).sendEmail("[email protected]");
Тест упадёт с ошибкой типа Wanted but not invoked
. Значит, что-то не так с логикой или параметрами.
Отрицательный кейс: вызван лишний раз
verify(emailService, times(2)).sendEmail("[email protected]");
Если метод был вызван только один раз, тест упадёт: Wanted 2 times but was 1
.
Проверка, что метод не вызывался
verify(emailService, never()).sendEmail(anyString());
Удобно, если нужно убедиться, что побочный эффект не произошёл.
Проверка порядка вызовов
InOrder inOrder = inOrder(emailService, logService);
inOrder.verify(emailService).sendEmail(anyString());
inOrder.verify(logService).log(anyString());
Mockito умеет проверять, что методы вызывались в нужном порядке — полезно для сложных сценариев.
Таблица сравнения: что будет, если…
Сценарий | Ожидание | Результат | Рекомендация |
---|---|---|---|
Метод вызван 1 раз, проверяем times(1) |
Проходит | OK | Всё хорошо |
Метод не вызван, проверяем times(1) |
Провал | Wanted but not invoked | Проверь логику теста |
Метод вызван 2 раза, проверяем times(1) |
Провал | Wanted 1 time but was 2 | Проверь, где лишний вызов |
Метод не вызван, проверяем never() |
Проходит | OK | Всё хорошо |
Полезные команды и сниппеты
// Проверить, что метод вызван ровно 3 раза
verify(service, times(3)).doSomething();
// Проверить, что метод вызван хотя бы раз
verify(service, atLeastOnce()).doSomething();
// Проверить, что метод вызван не более 2 раз
verify(service, atMost(2)).doSomething();
// Проверить, что метод вызван с любым параметром
verify(service).doSomething(anyString());
// Проверить, что метод вызван с конкретными параметрами
verify(service).doSomething(eq("foo"), anyInt());
Похожие решения, альтернативы и утилиты
- Mockito — де-факто стандарт для Java
- EasyMock — похожий подход, но менее гибкий и не такой популярный
- JMock — старичок, но синтаксис менее удобный
- MockK — для Kotlin, но тоже умеет verify
Mockito — самый популярный, поддерживается и развивается, интегрируется с JUnit, TestNG, Spring Boot и всем, что движется.
Статистика и сравнение
- Mockito — более 10 000 звезд на GitHub, используется в большинстве open-source Java проектов
- EasyMock — около 1 000 звезд, реже встречается в новых проектах
- JMock — почти не развивается, редко используется
По скорости и удобству Mockito выигрывает за счёт лаконичного API и кучи фич для проверки вызовов.
Интересные факты и нестандартные способы использования
- Можно мокать не только сервисы, но и статические методы (через Mockito-inline)
- Можно проверять не только количество вызовов, но и порядок, параметры, исключения
- Можно использовать
ArgumentCaptor
для захвата и анализа аргументов вызова - Можно интегрировать с CI/CD, чтобы тесты с
verify()
ловили регрессии до выката на прод - Можно писать свои кастомные
Answer
для сложных сценариев
Новые возможности и автоматизация
С помощью verify()
можно строить настоящие сценарии автоматизации: например, проверять, что при определённых условиях твой сервис не делает опасных операций (удаление, пересоздание, рассылка). Это особенно важно для серверных приложений, где ошибка может стоить дорого. В связке с CI/CD и скриптами тесты с verify()
становятся страховкой от человеческого фактора.
- Автоматическая проверка бизнес-логики при каждом коммите
- Быстрая отладка и поиск багов в цепочках вызовов
- Возможность писать тесты для legacy-кода без переписывания всей архитектуры
Выводы и рекомендации
Mockito.verify()
— это не просто инструмент для тестирования, а мощный способ контролировать поведение твоего кода. Он помогает ловить баги на ранних этапах, документировать логику, автоматизировать проверки и быть уверенным, что твой сервис делает ровно то, что должен. Если ты работаешь с серверным Java-кодом, автоматизируешь инфраструктуру или просто хочешь спать спокойно — обязательно внедри verify()
в свои тесты. Это быстро, просто и надёжно.
- Используй
verify()
для контроля побочных эффектов и безопасности - Пиши тесты с
verify()
для ключевых бизнес-операций - Интегрируй тесты с CI/CD для автоматической проверки на каждом этапе
- Не бойся экспериментировать с
ArgumentCaptor
и порядком вызовов
Официальная документация Mockito: https://site.mockito.org/
Если тебе нужен надёжный VPS для тестов, CI/CD или боевых задач — закажи VPS тут. Для максимальной производительности и кастомизации — выделенный сервер тут.
Прокачивай свои тесты, автоматизируй всё, что можно, и пусть баги обходят твой код стороной!
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.