Can PowerMock instantiate an inner class for test

2019-04-21 11:10发布

问题:

I'm attempting to test a class with a number of private classes (yes, I know this is generally considered poor practice for testability, but this question is not in regards to design principles). My class would look something like this:

public class EnclosingClass {
  .
  .
  .
  private class InnerClass implements InnerClassType {
     public InnerClass(){ /* do stuff */}
     public int InnerClassMethod();
  }
}
  • InnerClassType is a public interface

I've tried instantiating the classes with powermock by doing:

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

and also:

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

However, on both attempts I get a ConstructorNotFoundException

Is it possible to instantiate these inner classes? If so, where am I going wrong?

回答1:

You should be able to move past your ConstructorNotFoundExeception via the following mods to your first effort:

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

Since your inner class is not static, it implicitly expects a "this" reference from the outer class. Using this method, looks like you have to get explicit with it.



回答2:

You can mock it like this:

InnerClassType innerClass = (InnerClassType) Mockito.mock(
    Class.forName(EnclosingClass.class.getName() + "$InnerClass")
);