#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, как вы сказали. Спасибо за полезную информацию, я ценю вашу помощь, отличная работа!