Mockito возвращает null, когда я мокирую метод

Вопрос или проблема

У меня есть этот метод

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:
Обнаружены ненужные заглушки. Чистый и поддерживаемый тестовый код
не требует ненужного кода. Следующие заглушки ненужны
(щелкните, чтобы перейти к соответствующей строке кода):

  1. -> 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. Давайте рассмотрим, как можно решить эту проблему.

Понимание проблемы

  1. Метод mainMethod: В вашем методе mainMethod, вы вызываете метод vbsmClient.internalCall. Чтобы получить ожидаемое значение при тестировании, нам необходимо правильно замокировать этот метод.

  2. UnnecessaryStubbingException: Эта ошибка возникает, когда Mockito обнаруживает, что некоторые заглушки не нужны. Это может произойти по нескольким причинам, например, если заглушенный метод вообще не был вызван.

Возможные причины проблемы

  1. Несоответствие аргументов: Убедитесь, что аргументы, передаваемые в internalCall, точно соответствуют тому, что вы указали в заглушке. В вашем тесте вы используете anyMap(), что может не соответствовать использованию Map.of в вашем методе.

  2. Неправильный вызов метода: Если метод mainMethod не вызывает vbsmClient.internalCall так, как вы этого ожидаете, то заглушка никогда не сработает.

Решение

Вот шаги, которые помогут исправить вашу тестовую реализацию:

  1. Используйте корректные аргументы: Убедитесь, что аргументы, которые вы передаете в заглушку, точно соответствуют тем, которые метод mainMethod использует при вызове internalCall.

  2. Пример исправленного теста:

    @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 в вашем тестовом классе, и убедитесь, что все зависимости корректно замокированы. Надеюсь, это поможет вам решить вашу проблему.

Оцените материал
Добавить комментарий

Капча загружается...