Я не знаю других преимуществ, но хочу ответить на 2 ваших подвопроса (а это слишком долго для комментария):
разрешить насмешку без внедрения зависимости - это мне не понятно. Вы можете уточнить?
Я думаю, что это произошло на вики-странице , где описывается способ рефакторинга кода, чтобы не вызывать статические методы, чтобы сделать его тестируемым. Для конкретного примера того, что я думаю, к чему они приводят, допустим, у вас есть этот код, и вы хотите проверить метод, имитирующий поведение статического метода, без использования powermock:
public class MyClass {
public void doGetString() {
...
OtherClass.getString(); //It's complex and scary and needs mocking!
...
}
}
Одним из решений было бы перетянуть статический вызов в свой собственный объект, а затем внедрить объект, который можно смоделировать во время тестирования. Например, без использования других фреймворков это может выглядеть так:
public class MyClass {
public static class StringGetter {
public getString() {
return OtherClass.getString();
}
}
private final StringGetter getter;
//Existing Constructor
public MyClass() {
this(new StringGetter());
}
//DI Constructor
MyClass(StringGetter getter) {
this.getter = getter;
}
public void doGetString() {
...
getter.getString();
...
}
}
Я отделил поведение моего метода от поведения статического вызова и могу использовать конструктор DI, чтобы легко вводить макеты во время тестирования. Конечно, с помощью powermock я мог просто смоделировать статический метод и запустить с ним.
И нужно ли что-то жертвовать при использовании PowerMock?
Физически нет, но я бы сказал философски да :). Ниже приведены мои мнения, и я пытаюсь привести веские причины, но, конечно, они являются мнениями, поэтому примите их с недоверием:
Потенциально пугающая вещь, которая происходит с PowerMock, заключается в том, что для выполнения умений насмешливых приватных и статических методов они используют собственный загрузчик классов (которого не должно быть во время выполнения в производстве) и меняют байт-код из ваших классов. Возможно, это не должно иметь значения для подавляющего большинства классов большую часть времени, но если вы подумаете об этом, если байт-код изменился, и некоторые побочные эффекты больше не присутствуют, вы эффективно тестируете разные классы albiet на основе вашего существующие классы. Да, это очень академический аргумент.
Вы можете несколько смягчить этот первый аргумент, имея хорошую комплексную интеграцию и тесты более высокого уровня, которые не используют PowerMock. Таким образом, вы можете быть более уверенными в поведении ваших объектов, даже если ваши модульные тесты используют PowerMock.
Другой аргумент, который я имею против PowerMock, заключается в том, что он может слишком легко стать опорой. Я согласен с тем, что PowerMock может помочь в тестировании кода, использующего устаревший код, и другого кода, который вы не можете контролировать. Однако я бы сказал, что когда вы контролируете классы, которые вам нужны, вы должны избегать их использования. Если вы напишите класс с закрытым методом или статическим методом, который вам нужно явно смоделировать для проверки других методов, мой инстинкт инстинкта скажет, что этот метод может делать слишком много, и его следует реорганизовать и разбить. Имея PowerMock, уже доступный в проекте, у вас может возникнуть желание просто высмеять его и двигаться дальше, что уменьшит боль, которая должна побудить вас к тому же рефакторингу. Да, иногда это связано с различными техническими и нетехническими ограничениями, это невозможно, но лучше решать болевые точки, а не избегать их:)