Может ли PowerMock создать экземпляр внутреннего класса для тестовых случаев?

Я пытаюсь протестировать класс с несколькими частными классами (да, я знаю, что это обычно считается плохой практикой для тестируемости, но этот вопрос не касается принципов проектирования). Мой класс будет выглядеть примерно так:

public class EnclosingClass {
  .
  .
  .
  private class InnerClass implements InnerClassType {
     public InnerClass(){ /* do stuff */}
     public int InnerClassMethod();
  }
}
  • InnerClassType — общедоступный интерфейс

Я попытался создать классы с помощью powermock, выполнив:

Class clazz = Whitebox.getInnerClassType(EnclosingClass.class, "InnerClass");
Constructor constructor = Whitebox.getConstructor(clazz, null);
InnerClassType innerClass = (InnerClassType) constructor.newInstance(null);

а также:

Class clazz = Whitebox.getInnerClassType(EnclosingClass.class, "InnerClass");
InnerClassType innerClass = (InnerClassType) Whitebox.invokeConstructor(clazz);

Однако при обеих попытках я получаю ConstructorNotFoundException

Можно ли создать экземпляр этих внутренних классов? Если да, то где я ошибаюсь?


person josh-cain    schedule 02.11.2012    source источник


Ответы (2)


Вы должны быть в состоянии пройти мимо вашего ConstructorNotFoundExeception с помощью следующих модов до вашей первой попытки:

Class clazz = Whitebox.getInnerClassType(EnclosingClass.class, "InnerClass");
Constructor constructor = Whitebox.getConstructor(clazz, EnclosingClass.class);
InnerClassType innerClass = (InnerClassType) constructor.newInstance(new EnclosingClass());

Поскольку ваш внутренний класс не является статическим, он неявно ожидает ссылку "this" от внешнего класса. Используя этот метод, похоже, вы должны быть явными с ним.

person Brian Henry    schedule 06.11.2012
comment
Учитывая, что InnerClass является частным, как вы можете получить InnerClassType?? - person Victor Grazi; 20.05.2017

Вы можете издеваться над этим так:

InnerClassType innerClass = (InnerClassType) Mockito.mock(
    Class.forName(EnclosingClass.class.getName() + "$InnerClass")
);
person Samir    schedule 25.04.2018
comment
Это не отвечает на вопрос. Оператор намеревался создать экземпляр внутреннего класса для его проверки. Однако этот ответ вместо этого создает макет внутреннего класса. В этом макете по определению отсутствует код, который должен быть доступен для тестирования. - person Leviathan; 24.01.2019