Мокування статичного методу mockStatic()
Ще один важливий момент – мокування та верифікація статичних методів. "А що в цьому такого?", запитаєш ти. Так, статичні, але ж методи. Але це не так.
Пам'ятаєш з чого ми почали вивчення мок-об'єктів? З того, що ці об'єкти штучно створюються через клас DynamicProxy
. Статичні методи до жодних об'єктів не прив'язані, і перехопити виклики до них через DynamicProxy
не можна. От і все.
Але творці Mockito і тут змогли викрутитись – написали свій завантажувач класів і з його допомогою отримали змогу підміняти класи на льоту. Велика і складна робота, але вони таки змогли це зробити.
Потрібно додати ще одну бібліотеку до pom.xml
:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
Ось як потрібно працювати, якщо тобі потрібно мокувати статичний метод.
1. Створюємо спеціальний мок-об'єкт класу:
MockedStatic<Ім'яКласа>керуючийОб'єкт = Mockito.mockStatic(Ім'яКласу.class);
2. Додаємо до цього об'єкта правила роботи:
До цього об'єкта правила потрібно чіпляти іншими способами.
керуючийОб'єкт.when(Ім'яКласа::ім'яМетоду).thenReturn(результат);
3 Обов'язково загортаємо використання цього об'єкта в try-with-resources
, щоб об'єкт одразу видалився, і Mockito могло очистити пов'язані з ним правила.
Приклад:
@Test
void givenStaticMethodWithNoArgs () {
try (MockedStatic< StaticUtils> utilities = Mockito.mockStatic( StaticUtils.class)) {
//додаємо правило
utilities.when(StaticUtils::name).thenReturn("Привіт");
//перевіряємо, що правило працює
assertEquals("Привіт", StaticUtils.name());
}
}
Не так гарно, як з анотаціями @Mock
і @Spy
, проте дуже практично. Було дуже важко писати тести, доки не можна було замокати простий статичний метод, який використовувався всередині методів, що тестуються.