Я считаю, что между этими подходами нет существенной разницы.
Подход InjectMocks
На самом деле, чтобы он работал, ваш класс должен принимать зависимости через конструктор или сеттеры (и он никогда не работает с обоими). Я бы сказал, что этот подход упрощает тестирование, потому что вы вводите все, что хотите, в свой объект класса на этапе инициализации.
class Foo {
private final Bar bar;
public Foo(final Bar bar) {
this.bar = bar;
}
}
Если это наш тестируемый класс, тогда все, что делает @InjectMock, - это создает mocks и сделайте следующее:
Foo foo = new Foo(barMock);
Помимо возможности тестирования, представьте, что если Bar
является интерфейсом, то вы можете переключаться между несколькими его реализациями, не касаясь кода класса ( в идеале). Если у вас есть структура DI, это еще проще. Итак, в основном этот формат класса делает его гибким.
Использование однострочных методов для создания объекта
Допустим, это наш тестируемый класс. Как видите, я инициализирую свойство внутри конструктора. Юридически, без отражения magi c, я не могу поставить фиктивную переменную bar
ни во время инициализации, ни после этого. Метод или помощник Factory состоит в том, что:
- Mockito не может имитировать конструкторы, что означает, что вы не можете поместить фиктивный объект вместо
bar
без отражения, и вы можете сделать это только после инициализации. В общем, с моей точки зрения на тестирование, следует избегать отражения в максимально возможной степени. - Однострочные функции выглядят так же чисто, как и конструкторы, и могут быть описательными (как стандартные c фабричные методы).
Итак, когда вы переключаете свой класс, чтобы он выглядел так:
class Foo {
private final Bar bar;
public Foo() {
this.bar = makeBar();
}
Bar makeBar() {
return new Bar();
}
}
Теперь вы можете поставить шпиона и просто имитировать метод makeBar
. То же относится и к заводскому методу. Честно говоря, фабричный подход мне кажется многословным, но все же я уверен, что будут времена, когда он может пригодиться.