Вопрос или проблема
У меня есть этот метод
private String mainMethod(String param) {
String response = vbsmClient.internalCall(EnumValue, Map.of(
"key1", param,
"key2", 1
), String.class);
}
Где определение internalCall выглядит так
public <T> T internalCall(final MyEnum e, final Map<String, Object> params, Class<T> classType) {
final String response = internalCall(e, Collections.unmodifiableMap(params));
return convert(response, classType);
}
А мой тестовый класс для основного метода выглядит так:
@Test
void test() {
Map<String, Object> map = Map.of(
"key1", "123",
"key2", 1
);
Mockito.when(vbsmClient.internalCall(eq(MyEnum.EnumValue), anyMap(), eq(String.class))).thenReturn("Success");
ReflectionTestUtils.invokeMethod(serviceClass, "mainMethod", "123456");
}
Но мок не работает, и вместо того, чтобы вернуть строку “Success”, я получаю
org.mockito.exceptions.misusing.UnnecessaryStubbingException:
Обнаружены ненужные заглушки. Чистый и поддерживаемый тестовый код
не требует ненужного кода. Следующие заглушки ненужны
(щелкните, чтобы перейти к соответствующей строке кода):
- -> at com.vz.s360.incident.services.ticket.TicketServiceImplTest.test(TicketServiceImplTest.java:271)
Пожалуйста, удалите ненужные заглушки или используйте «ленивую» строгость.
Дополнительная информация: javadoc для класса UnnecessaryStubbingException.at
org.mockito.junit.jupiter.MockitoExtension.afterEach(MockitoExtension.java:197)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Я пробовал много вещей, например
Mockito.when(vbsmClient.internalCall(any(), any(), any())).thenReturn("Success");
но ничего из этого не сработало. Я не уверен, почему Mockito не распознает мой мок.
Есть идеи?
Ответ или решение
Проблема, с которой вы столкнулись, связана с тем, что Mockito не распознает ваш мок, что приводит к тому, что метод internalCall
не возвращает ожидаемое значение, а вместо этого вызывает ошибку UnnecessaryStubbingException. Давайте рассмотрим, как можно решить эту проблему.
Понимание проблемы
-
Метод mainMethod: В вашем методе
mainMethod
, вы вызываете методvbsmClient.internalCall
. Чтобы получить ожидаемое значение при тестировании, нам необходимо правильно замокировать этот метод. -
UnnecessaryStubbingException: Эта ошибка возникает, когда Mockito обнаруживает, что некоторые заглушки не нужны. Это может произойти по нескольким причинам, например, если заглушенный метод вообще не был вызван.
Возможные причины проблемы
-
Несоответствие аргументов: Убедитесь, что аргументы, передаваемые в
internalCall
, точно соответствуют тому, что вы указали в заглушке. В вашем тесте вы используетеanyMap()
, что может не соответствовать использованиюMap.of
в вашем методе. -
Неправильный вызов метода: Если метод
mainMethod
не вызываетvbsmClient.internalCall
так, как вы этого ожидаете, то заглушка никогда не сработает.
Решение
Вот шаги, которые помогут исправить вашу тестовую реализацию:
-
Используйте корректные аргументы: Убедитесь, что аргументы, которые вы передаете в заглушку, точно соответствуют тем, которые метод
mainMethod
использует при вызовеinternalCall
. -
Пример исправленного теста:
@Test void test() { // Убедитесь, что вы замокируете метод с корректными аргументами. Mockito.when(vbsmClient.internalCall(eq(MyEnum.EnumValue), argThat(map -> map.size() == 2 && "key1".equals(map.get("key1")) && 1 == map.get("key2")), eq(String.class))) .thenReturn("Success"); // Вызываем метод, который мы тестируем String result = ReflectionTestUtils.invokeMethod(serviceClass, "mainMethod", "123"); // Проверяем результат assertEquals("Success", result); }
Объяснение изменений
- argThat: Здесь мы используем
argThat
, чтобы убедиться, что передаваемая мапа содержит ожидаемые ключи и значения. - Проверка результата: Не забудьте проверить результат метода
mainMethod
, чтобы убедиться, что он возвращает ожидаемое значение.
Заключение
Эти изменения должны помочь вам избежать этой проблемы с Mockito. Если ошибка продолжает возникать, проверьте, правильно ли настроен vbsmClient
в вашем тестовом классе, и убедитесь, что все зависимости корректно замокированы. Надеюсь, это поможет вам решить вашу проблему.