Я прочитал несколько веток здесь о статических методах, и я думаю, что я понимаю проблемы неправильного использования / чрезмерного использования статических методов. Но я не до конца понял, почему трудно высмеивать статические методы.
Я знаю, что другие насмешливые фреймворки, такие как PowerMock, могут это делать, но почему не может Mockito?
Я читал эту статью , но автор, похоже, религиозно против слова static
, возможно, это мое плохое понимание.
Простое объяснение / ссылка было бы здорово.
Ответы:
Я думаю, что причина может заключаться в том, что библиотеки фиктивных объектов обычно создают фиктивные путем динамического создания классов во время выполнения (используя cglib ). Это означает, что они либо реализуют интерфейс во время выполнения (это то, что делает EasyMock, если я не ошибаюсь), либо они наследуют от класса для имитации (это то, что делает Mockito, если я не ошибаюсь). Оба подхода не работают для статических членов, поскольку вы не можете переопределить их, используя наследование.
Единственный способ макетировать статику - это модифицировать байт-код класса во время выполнения, что, я полагаю, немного сложнее, чем наследование.
Это мое предположение, для чего это стоит ...
источник
Если вам нужно издеваться над статическим методом, это сильный показатель плохого дизайна. Обычно вы издеваетесь над зависимостью вашего тестируемого класса. Если ваш тестируемый класс ссылается на статический метод - например, java.util.Math # sin - это означает, что тестируемому классу нужна именно эта реализация (например, точность или скорость). Если вы хотите абстрагироваться от конкретной реализации пазухи, вам, вероятно, нужен интерфейс (вы видите, к чему это приведет)?
источник
Я серьезно думаю, что это запах кода, если вам нужно высмеивать и статические методы.
Единственный раз, когда это кажется мне излишним, это библиотеки вроде Guava, но вам не нужно все равно издеваться над этим, потому что это часть логики ... (например, Iterables.transform (..))
Таким образом, ваш собственный код остается чистым, вы можете смоделировать все ваши зависимости в чистом виде, и у вас есть антикоррупционный слой против внешних зависимостей. Я видел PowerMock на практике, и все классы, для которых он был нужен, были плохо спроектированы. Также временами интеграция PowerMock вызывала серьезные проблемы
(например, https://code.google.com/p/powermock/issues/detail?id=355 ).
PS: То же самое касается и частных методов. Я не думаю, что тесты должны знать о деталях частных методов. Если класс настолько сложен, что возникает соблазн издеваться над частными методами, это, вероятно, признак разделения этого класса ...
источник
@Inject SomeDependency
и в моей конфигурации я определяюbind(SomeDependency.class).in(Singleton.class)
. Таким образом, если завтра это больше не Singleton, я изменю один конфиг и все.Foo.getInstance()
везде. Я просто написал синглтон в ответ, чтобы противостоять аргументу, «но статический метод не требует создания множества объектов-оболочек». Кроме того, концептуально для меня есть небольшая разница между статическим методом и методом экземпляра в синглтоне, просто вы не можете издеваться над этим синглтоном. Но синглтон или нет - это совсем не то, что я пытался сделать, смысл в том, чтобы вводить и высмеивать коллабораторов, а не вызывать статические методы, если это затрудняет тестирование.Mockito возвращает объекты, но static означает «уровень класса, а не уровень объекта», поэтому mockito выдаст исключение нулевого указателя для static.
источник
В некоторых случаях статические методы могут быть сложны для тестирования, особенно если их нужно смоделировать, поэтому большинство фреймворк-фреймворков их не поддерживают. Я обнаружил, что это сообщение в блоге очень полезно для определения того, как высмеивать статические методы и классы.
источник