Что делает Mockito.mock и предложения, почему эта реализация не будет работать при избавлении от Mockito

#java #mockito

#java #mockito

Вопрос:

У меня есть следующий интерфейс CatalogVersionService , который предоставляет некоторые сервисы. Также у меня есть модульный тест, который имитирует этот интерфейс с помощью Mockito следующим образом:

 CatalogVersionService catalogVersionService  = Mockito.mock(CatalogVersionService.class);
  

И вводит catalogVersionService в реализацию распознавателя, названную DefaultClassificationClassResolverService следующим образом:

 ((DefaultClassificationClassResolverService) ccrservice).setCatalogVersionService(catalogVersionService);

// Assert that my resolver will find a single ClassificationClassModel object
ClassificationClassModel single = new ClassificationClassModel();
        assertTrue(ccrservice.resolve(single).contains(single)); //resolver
  

До этого момента все работало нормально, пока я не попытаюсь создать интеграционный тест и избавиться от издевательского CatalogVersionService интерфейса. Насколько мне известно, Mockito.mock создает макет объекта данного класса или интерфейса, в данном случае CatalogVersionService который реализован DefaultCatalogVersionService . Итак, когда я пытаюсь получить реальный объект, я делаю что-то вроде этого:

 catalogVersionService = new DefaultCatalogVersionService();
((DefaultClassificationClassResolverService) ccrservice).setCatalogVersionService(catalogVersionService);
  

Однако после этого момента я получаю исключение с нулевым указателем, и мой тест на распознавание, конечно, завершается неудачей. Итак, что на самом деле делает Mockito.mock?? Хороший ли это подход, предполагающий:

 CatalogVersionService catalogVersionService  = Mockito.mock(CatalogVersionService.class);
// IS EQUIVALENT TO:
catalogVersionService = new DefaultCatalogVersionService();
  

Есть идеи, почему не выполняется assert?

Заранее спасибо

Ответ №1:

Нет, неверно предполагать, что это Mockito.mock(...) то же самое, что создание экземпляра вашего DefaultCatalogVersionService . Это не то, что делают mocks.

Если вы получаете исключение NullPointerException при использовании concrete DefaultCatalogVersionService , это наводит на мысль, что что-то равно null в DefaultCatalogVersionService !

Вы изучили stacktrace, чтобы увидеть, в какой строке возникает исключение NullPointerException, которое помогло бы вам определить, какое свойство / поле равно null?

Более чем вероятно, что ваш DefaultCatalogVersionService зависит от других классов, которые вы не подключаете в своем тесте.

Комментарии:

1. спасибо @ matt b за ваш ответ, но тогда как Mockito.mock(CatalogVersionService.class ); подключает все?

2. Это не так. Он создает динамический макет объекта, который реализует интерфейс CatalogVersionService, но он не знает, как реагировать на вызовы метода самостоятельно. Чтобы сообщить Mockito, что делать, когда CatalogVersionService. Вызывается doSomething(), вы используете when(mock.doSomething()).thenReturn(..) , и чтобы убедиться, что класс, использующий CatalogVersionService , вызвал методы, которые вы ожидаете от него, вы используете verify(mock).something() . Взгляните на документацию mockito .

3. Однако Mockito не имеет никакого отношения к тому, почему вы получаете NPE при использовании реального класса. Это, вероятно, потому, что реализация по умолчанию зависит от других объектов, которые вы не создали. С Mockito вы не замечаете, когда методы вызываются без каких-либо определений поведения, потому что издеваемые методы «ничего не делают» по умолчанию.

4. Привет @ matt b к сожалению, я не могу проголосовать за тебя, потому что у меня недостаточно репутации, но. Теперь это работает, у меня не было моего DefaultCatalogVersionService, должным образом подключенного к файлу конфигурации spring, как вы сказали. Спасибо за полезную информацию, я ценю вашу помощь, отличная работа!