Можно ли вводить макеты в поля суперкласса, которые имеют то же имя и тип, что и дочерний класс.
В моей ситуации у меня есть класс контроллера
abstract class BaseController {
protected AccessManager accessManager;
}
Он расширен классом, как показано ниже:
class ApiController<T> extends BaseController {
}
И, наконец, более специализированный контроллер расширяет его следующим образом:
class PersonController extends ApiController<Person> {
private AccessManager accessManager;
}
Я пишу модульные тесты для PersonController, и во время его тестирования некоторые из его методов вызывают метод BaseController, который делегатами вызывает его объект-член protected, которым всегда является null.
Я пробовал использовать @InjectMocks и использовал ReflectionTestUtils.setField для установки защищенного поля BaseController, но эти методы заканчивают настройкой поля только в классе PersonController, потому что их имена и типы одинаковы.
Я потратил на это много времени, но не смог решить. Пожалуйста помоги. Спасибо
Я не могу это изменить, потому что моя работа - только писать тестовые примеры. Дизайн - это не моя сфера
Покажите, как вы используете ReflectionTestUtils? Есть метод setField, который принимает "целевой класс"? Вы должны иметь возможность указать целевой класс как BaseController.class.




Как упоминал @strelok, вы можете просто использовать метод со следующей подписью
public static void setField(@Nullable Object targetObject, @Nullable Class<?> targetClass, @Nullable String name, @Nullable Object value, @Nullable Class<?> type)
Это требует, чтобы вы указали, какой класс использовать во время настройки поля, например Parent или Child
public class Parent {
private String name;
public String getName() {
return name;
}
}
public class Child extends Parent {
private String name;
public String getName() {
return name;
}
public void printNames() {
System.out.println("I'm " + this.name);
System.out.println("My father is " + super.getName());
}
}
public class Main {
public static void main(String[] args) {
Child child = new Child();
ReflectionTestUtils.setField(child,Parent.class, "name", "fatah",String.class);
ReflectionTestUtils.setField(child,Child.class, "name", "abdul",String.class);
child.printNames();
}
}
И вы не можете изменить (неоптимальный) дизайн ваших классов контроллеров? Вы можете просто найти все поля с этим именем, используя обычное отражение (от каждого суперкласса), и установить его вручную.