3

I have following public class in Java which looks like:

public class MyClass 
{

  private static class MyNestedClass<T> extends SomeOtherClass
  {
  }

}

I am writing a test where I need to create a mock object for MyNestedClass class using PowerMockito, but am not able to access the class since it's private. Is there a way I can access MyNestedClass?

I tried the following:

MyClass.MyNestedClass myNestedClass = new MyClass.MyNestedClass()

and

MyClass testNoteActivity = Mockito.spy(MyClass.class);
testNoteActivity.MyNestedClass myNestedClass = new testNoteActivity.MyNestedClass()

Both didn't work for me.

baao
  • 71,625
  • 17
  • 143
  • 203
tech_human
  • 6,592
  • 16
  • 65
  • 107
  • Is there no other way? By definition this class is private, you would have to change the scope to package in order to test it. Maybe you can spy on a method that uses this class instance, if you can work with SomeOtherClass, which is not private. – Beri Sep 13 '17 at 18:06
  • 1
    If test code needs to access that class then perhaps it shouldn't be a private (static) class. Powermock is usually the last resort and if you have control over the codebase, I'd suggest you consider refactoring the code or reconsider what you're testing. – Mick Mnemonic Sep 13 '17 at 18:08

1 Answers1

5

You can access private classes via reflection:

final Class<?> nestedClass = Class.forName("MyClass$MyNestedClass");
final Constructor<?> ctor = nestedClass.getDeclaredConstructors()[0];
ctor.setAccessible(true);
final Object instance = ctor.newInstance();
System.out.println(instance);

but it's not very good practice.

To find class with Class.forName you should provide full class name including package. E.g. if MyClass located in com.test package this string should be "com.test.MyClass$MyNestedClass".

Kirill
  • 7,580
  • 6
  • 44
  • 95