Mockito - Как вводить макеты, если суперкласс содержит поле с тем же именем и типом, что и дочерний класс

Можно ли вводить макеты в поля суперкласса, которые имеют то же имя и тип, что и дочерний класс.

В моей ситуации у меня есть класс контроллера

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, потому что их имена и типы одинаковы.

Я потратил на это много времени, но не смог решить. Пожалуйста помоги. Спасибо

И вы не можете изменить (неоптимальный) дизайн ваших классов контроллеров? Вы можете просто найти все поля с этим именем, используя обычное отражение (от каждого суперкласса), и установить его вручную.

Strelok 30.07.2018 23:54

Я не могу это изменить, потому что моя работа - только писать тестовые примеры. Дизайн - это не моя сфера

Abdul Fatah 31.07.2018 00:00

Покажите, как вы используете ReflectionTestUtils? Есть метод setField, который принимает "целевой класс"? Вы должны иметь возможность указать целевой класс как BaseController.class.

Strelok 31.07.2018 08:54
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
3
2 487
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как упоминал @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();
    }
}

Другие вопросы по теме