Почему Mockito не высмеивает статические методы? - PullRequest
237 голосов
/ 19 декабря 2010

Я прочитал несколько веток здесь о статических методах, и я думаю, что я понимаю проблемы, которые могут вызывать неправильное использование / чрезмерное использование статических методов.Но я не до конца понял, почему сложно издеваться над статическими методами.

Я знаю, что другие среды насмешки, такие как PowerMock, могут это делать, но почему Mockito не может?

Я прочитал эту статью , но автор, похоже, религиозно настроен против слова static, может быть, это мое плохое понимание.

Было бы неплохо простое объяснение / ссылка.

Ответы [ 5 ]

217 голосов
/ 19 декабря 2010

Я думаю, что причина может заключаться в том, что библиотеки фиктивных объектов обычно создают фиктивные путем динамического создания классов во время выполнения (используя cglib ).Это означает, что они либо реализуют интерфейс во время выполнения (это то, что делает EasyMock, если я не ошибаюсь), либо они наследуют от класса для имитации (это то, что делает Mockito, если я не ошибаюсь).Оба подхода не работают для статических членов, так как вы не можете переопределить их, используя наследование.

Единственный способ смоделировать статику - изменить байт-код класса во время выполнения, котороепредположим, это немного сложнее, чем наследование.

Это мое предположение, для чего оно стоит ...

28 голосов
/ 19 декабря 2010

Если вам нужно издеваться над статическим методом, это сильный показатель плохого дизайна.Обычно вы издеваетесь над зависимостью вашего тестируемого класса.Если тестируемый класс ссылается на статический метод - например, java.util.Math # sin - это означает, что тестируемому классу нужна именно эта реализация (например, точность или скорость).Если вы хотите абстрагироваться от конкретной синусовой реализации, вам, вероятно, нужен интерфейс (вы видите, куда это идет)?

6 голосов
/ 21 июля 2014

Я серьезно думаю, что это запах кода, если вам тоже нужно высмеивать статические методы.

  • Статические методы для доступа к общим функциям? -> Используйте экземпляр синглтона и введите
  • Сторонний код? -> Оберните его в свой собственный интерфейс / делегат (и, при необходимости, сделайте его тоже одиночным)

Единственный случай, когда мне кажется, что это излишне, это библиотеки вроде Guava, но вам не нужно все равно издеваться над этим, потому что это часть логики ... (например, Iterables.transform (..))
Таким образом, ваш собственный код остается чистым, вы можете чистым образом смоделировать все ваши зависимости, и у вас есть антикоррупционный уровень против внешних зависимостей. Я видел PowerMock на практике, и все классы, для которых он был нужен, были плохо спроектированы. Также временами интеграция PowerMock вызывала серьезные проблемы
(например, https://code.google.com/p/powermock/issues/detail?id=355)

PS: То же самое относится и к закрытым методам. Я не думаю, что тесты должны знать о деталях частных методов. Если класс настолько сложен, что у него возникает соблазн издеваться над частными методами, это, вероятно, признак разделения этого класса ...

4 голосов
/ 27 ноября 2014

Mockito возвращает объекты, но static означает «уровень класса, а не уровень объекта», поэтому mockito выдаст исключение нулевого указателя для static.

1 голос
/ 19 декабря 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...