6.1 Мокирование статического метода 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, зато очень практично. Было очень тяжело писать тесты, когда нельзя было замокать простой статический метод, который использовался внутри тестируемых методов.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ