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

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

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

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

Спасибо.


person austen    schedule 12.01.2010    source источник
comment
Делать все классы final определенно не лучшая практика... прошло некоторое время с тех пор, как я читал "Эффективную Java", но консенсус связанного потока, похоже, тоже не подразумевает этого. Вы должны пометить классы final, чтобы указать, что по какой-то причине их не следует расширять - если нет, это просто добавляет ненужную сложность - как вы обнаружили. Кроме того, если вы понимаете, что вам нужно расширить класс где-то в будущем, вам придется изменить код исходного класса, чтобы написать новый класс, что нарушает принцип Open/Closed.   -  person Nate    schedule 13.01.2010


Ответы (3)


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

  1. Возможность убедиться, что кто-то не наследует от вашего класса, ИЛИ
  2. Возможность убедиться, что ваш код можно тестировать, используя выбранную вами фиктивную среду?

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

person Kaleb Pederson    schedule 12.01.2010
comment
Тестируемость гораздо важнее, ИМХО, и я считаю, что она подходит для нашей ситуации. - person austen; 13.01.2010
comment
Нет необходимости жертвовать дизайном ради тестируемости. Вы можете получить и то, и другое, просто используя правильный инструмент для работы. В этом случае используйте один из инструментов имитации Java, который может имитировать окончательные методы и классы: JMockit (мой собственный инструмент) или PowerMock (который поддерживает Mockito API, поэтому вам не нужно полностью переписывать существующие тесты). - person Rogério; 08.06.2010

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

person Laurence Gonsalves    schedule 12.01.2010

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

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

В этом документе об использовании фиктивных объектов Эндо-тестирование: модульное тестирование с фиктивными объектами есть раздел ( 4.4) под названием Обнаружение интерфейса, в котором объясняется, как фиктивные объекты помогают в обнаружении интерфейсов.

person sateesh    schedule 13.01.2010
comment
Мне нравится идея открытия интерфейса. - person austen; 13.01.2010
comment
Когда я пишу код, который использует окончательный класс, и этот класс не реализует отдельный интерфейс, я не нарушаю интерфейс программы, а не принцип реализации GoF. Этот принцип не требует, чтобы каждый класс реализовывал отдельный интерфейс. Другие части книги GoF разъясняют это тем, кто действительно хочет ее прочитать. - person Rogério; 08.06.2010