Что делать, когда Java Best Practices конфликтует с Mockito

Моя команда разработчиков начала использовать Mockito и имеет классы, которые были определены как "final". Я прочитал в "Эффективной Java" Джошуа Блоха и в потоке SO Когда использовать окончательный вариант, чтобы все классы использовали последний модификатор. В потоке было некоторое несогласие, но я согласен с идеей форсировать состав класса, если наследование не имеет смысла.

Что делать, если я хочу тестировать классы с использованием инфраструктуры тестирования, такой как Mockito, которая требует, чтобы классы не имели "окончательного" модификатора?. Я надеюсь, что кто-то другой столкнулся с подобными проблемами во время их развитие. В каких резолюциях ваша команда разработчиков прибыла?

Есть два очевидных ответа, таких как использование JMock или удаление "final" модификатора для классов, которые мы хотим протестировать, но мы хотим придерживаться одной внешней среды тестирования (помимо JUnit), и может быть трудно убедить других разработчиков для удаления модификатора 'final'.

Спасибо.

Ответ 1

Что вам больше всего нужно:

  • Возможность убедиться, что кто-то не наследует ваш класс, OR
  • Возможность убедиться, что ваш код можно тестировать, используя вашу насмешливую структуру выбора?

Как правило, я считаю, что вам не нужно принуждать (1). Для меня гораздо важнее тестируемость (2). Что лучше всего подходит вашей ситуации?

Ответ 2

Если вы хотите, чтобы ваши классы были окончательными, вы можете реализовать их интерфейсы. Интерфейсы являются макетными.

Ответ 3

Как уже упоминалось в другом ответе, вы можете сделать свои заключительные классы для реализации интерфейс (интерфейсы) и в ваших тестах обманывают интерфейс (интерфейсы).

Это одно из преимуществ использования объектов Mock; в таких сценариях они заставляют вас думать о том, как код может быть лучше организован. Если ваша база кода имеет много ссылок на конечные классы (таким образом, она связана с конкретной реализацией), это нарушает принцип OO "программирования для интерфейса", а необходимость лучшей проверки позволяет вам думать о рефакторинге, чтобы исключить зависимость от конкретных реализаций.

Настоящая статья об использовании Mock Objects Endo-testing: Unit Testing with Mock Objects имеет раздел (4.4) под названием Обнаружение интерфейса, объясняющее, как макетные объекты помогают в обнаружении интерфейсов.