Употребление ArgumentCaptor для стаббинга в Mockito: гайд
Быстрый ответ
ArgumentCaptor создаётся через вызов ArgumentCaptor.forClass(YourClass.class)
. Чтобы перехватить аргументы, воспользуйтесь captor.capture()
в Mockito.when()
или doReturn()
. Получить значение аргумента можно через captor.getValue()
после вызова метода.
Пример:
ArgumentCaptor<YourClass> captor = ArgumentCaptor.forClass(YourClass.class);
when(yourMock.methodToStub(captor.capture())).thenReturn(mockedResult);
yourMock.methodToStub(actualArgument);
YourClass captured = captor.getValue();
Помните, ArgumentCaptor нужен не для обманывания, а для анализа и проверки вызовов методов.
Применение ArgumentCaptor
ArgumentCaptor является удобным инструментом для перехвата и анализа аргументов методов, но его применение как мока не рекомендуется в руководстве Mockito.
Стратегия: Создание моков против проверок
Создание моков обеспечивает контрольное поведение мок-объекта, а проверка должна быть выполнена для анализа вызовов. Первое аналогично планированию преступления, второе — расследованию его.
Использование Matcher'ов при создании моков
Для ожидания конкретных аргументов используйте Matcher'ы такие как eq()
, а для более гибкой настройки можно использовать Matchers.any()
.
Пример использования eq():
when(yourMock.methodToStub(eq(expectedArgument))).thenReturn(mockedResult);
Реализация equals для эффективного сопоставления
Если вам логично использовать Matcher'ы во множестве тестов, создайте собственную реализацию метода equals
для стабильного сравнения.
Умное создание моков
Для создания моков с продвинутой логикой используйте doReturn()
вместе с argThat()
и кастомными Matcher'ами.
doReturn(mockedResult).when(yourMock).methodToStub(argThat(new MyCustomMatcher()));
Избегайте возвращения null: реальность моков
Постарайтесь не возвращать null из мок-объектов. Лучше использовать Optional или аналогичные конструкции.
Укрепляйте свои тесты
Повышение надежности тестов
Усилить свои тесты дополнительно можно с помощью ArgumentCaptor и специфических Matcher'ов, чтобы улучшить их качество.
Проверки: зал славы
Используйте verify
в композиции с классом ArgumentCaptor, чтобы увеличить надежность контроля за аргументами методов.
verify(yourMock).methodToStub(captor.capture());
YourClass capturedParam = captor.getValue();
assertEquals(expectedParam, capturedParam);
Осознайте ограничения и применяйте лучшие подходы
Осведомленность об ограничениях ArgumentCaptor и соблюдение лучших практик помогает поддерживать код в должном состоянии.
Визуализация
Работу ArgumentCaptor в Mockito можно представить, как фотографическую камеру, которая фиксирует аргументы при вызове метода:
При вызове метода:
👨💼🗣️ -> 📞📲 (Вызов метода и его аргументы)
ArgumentCaptor в действии:
👨💼🗣️ -> 📷 -> 📞📲 (Захват аргументов)
После вызова метода происходит анализ аргументов:
Анализ зафиксированных аргументов:
🖼️ (Аргументы) -> 🕵️♂️ (Анализ в тестах)
ArgumentCaptor<Type> argumentCaptor = ArgumentCaptor.forClass(Type.class);
verify(mockObject).yourMethod(argumentCaptor.capture());
Type capturedArgument = argumentCaptor.getValue();
Смотрим, соответствуют ли захваченные аргументы ожидаемым:
Сравниваем зафиксированные аргументы (🖼️) с ожидаемыми (🎯)
Полезные материалы
- ArgumentCaptor – mockito-core 5.10.0 javadoc – Официальная документация Mockito.
- Unit tests with Mockito – Tutorial – Подробное руководство от Vogella.
- Mockito's ArgumentCaptor: Перехват аргументов для дальнейших проверок – DZone – Пошаговый гид по использованию ArgumentCaptor.
- Часто задаваемые вопросы по использованию ArgumentCaptor · mockito/mockito Wiki · GitHub.
- Видеоурок по ArgumentCaptor от Java Brains – YouTube.