Я пытаюсь протестировать класс, который создает новый объект внутри конструктора. Я использую PowerMock с Mockito.

public ClassNeedToTest() throws Exception {

    String targetCategory = "somevalue";
    String targetService = "somevalue";
    invoker = new ServiceInvoker(targetCategory, targetService); // throws Exception
}

Для приведенного выше кода я пытаюсь создать экземпляр ClassNeedToTest, чтобы протестировать другой метод этого класса. Я не могу создать объект, потому что создание ServiceInvoker вызывает исключение. Класс ServiceInvoker является сторонним классом. Есть ли способ имитировать ServiceInvoker, чтобы, когда тестовый класс пытается создать ClassNeedToTest, я мог получить имитирующий объект ServiceInvoker вместо реального вызова конструктора ServiceInvoker.

В моем тестовом классе я просто создаю новый экземпляр ClassNeedToTest:

ClassNeedToTest obj = new ClassNeedToTest();
6
Varun 6 Мар 2014 в 10:11

2 ответа

Лучший ответ

Я нашел ответ на то же самое. Если вы правильно выполните шаги, приведенные ниже, вы можете издеваться над объектами.

Шаг 1. - Добавьте аннотацию для подготовки тестового класса.

@PrepareForTest({ ServiceInvoker.class, ClassNeedToTest.class})

Шаг 2. - Насмехайтесь над классом.

serviceInvokerMck = Mockito.mock(ServiceInvoker.class);

Шаг 3. Используйте метод ниже, чтобы имитировать объект при вызове оператора new.

PowerMockito.whenNew(ServiceInvoker.class).withAnyArguments().thenReturn(serviceInvokerMck);

Чего я не делал, так это добавления класса ClassNeedToTest в аннотацию PrepareForTest, думая, что туда следует добавить единственный класс, который нужно смоделировать.

4
NoobEditor 4 Апр 2018 в 09:46

Создание объектов в конструкторе класса - плохая практика (принцип инверсии зависимостей). Обычный способ протестировать такой код - это добавить новый конструктор, являющийся частным пакетом.

public ClassNeedToTest() throws Exception {
  this(new ServiceInvoker("somevalue", "somevalue"));
}

ClassNeedToTest(ServiceInvoker invoker) throws Exception {
  this.invoker = invoker;
}

В ваших тестах можно использовать новый конструктор с макетом ServiceInvoker. После этого вы можете сделать новый конструктор общедоступным и провести рефакторинг кода, чтобы использовать только новый конструктор.

0
Stefan Birkner 6 Мар 2014 в 09:22