Дано два правила, которые имеют совершенно разные задачи и зависимости использовать.
Чтобы сделать их пригодными для модульного тестирования, я внедряю эти зависимости через конструктор.
Код: Выделить всё
class RuleA implements MyInterface {
private DependencyA_1 dependencyA1;
private DependencyA_2 dependencyA2;
public RuleA(DependencyA_1 dependencyA1, DependencyA_2 dependencyA2) {
this.dependencyA1 = dependencyA1;
this.dependencyA2 = dependencyA2;
}
public Result execute() {
....
}
Код: Выделить всё
class RuleB implements MyInterface {
private DependencyB_1 dependencyB1;
private DependencyB_2 dependencyB2;
public RuleB(DependencyB_1 dependencyB1, DependencyB_2 dependencyB2) {
this.dependencyB1 = dependencyB1;
this.dependencyB2 = dependencyB2;
}
public Result execute() {
....
}
Но если Я делаю это: моя фабрика должна знать каждую зависимость всех моих правил, что (по моему мнению) является большой проблемой связи, и если я хочу провести модульное тестирование своей фабрики, мне нужно высмеять все эти зависимости , о чем моя фабрика не должна знать.
Поэтому для производственного кода я бы добавил конструкторы без аргументов в RuleA и RuleB, в которых создаются экземпляры "реальных" объектов, например:
Код: Выделить всё
public RuleA(DependencyA_1 dependencyA1, DependencyA_2 dependencyA2) {
this.dependencyA1 = dependencyA1;
this.dependencyA2 = dependencyA2;
}
public RuleA() {
this(new MyProductiveDependencyA1(), new MyProductiveDependencyA2());
}
....
Код: Выделить всё
class Factory {
public MyInterface createClass(String type) {
if ("A".equals(type)) {
return new RuleA();
}
if ("B".equals(type)) {
return new RuleB();
}
}
Поэтому мои вопросы:
Хорош ли шаблон использовать один конструктор для модульного тестирования и еще один для «нормального/производственного» использования (если, конечно, в нем нет логики)?
Если я использую конструктор модульного тестирования при вызове классов, им нужно знать все зависимости вызываемого класса, а если подумать о более глубоких иерархиях, это может стать очень запутанным. Если я использую конструктор без аргументов, вызывающий класс не подлежит модульному тестированию. Что мне делать? Нужно ли мне признать, что эти классы можно тестировать только в интеграционных тестах или это запах плохого дизайна программного обеспечения?
Я знаю, что есть пара фреймворков внедрения зависимостей, использующих аннотации, чтобы я мог имитировать необходимые зависимости, не передавая их через конструкторы, но я хотел бы избегать их, если это возможно.
Подробнее здесь: https://stackoverflow.com/questions/791 ... es-in-call
Мобильная версия