Imagine that you need to test some piece of code which needs a 3th part developed class that is placed into a non-controllable library and you need to get some mockup of the class, of course you will use a mockup framework like Mockito and will not get any problem if the class is a usual "right" class but imagine that the class is not so usual one but it is a final one and furthermore it has a private constructor (because you have to create it through a special class factory method). In the case the Mockito framework will tell you "sorry, it is a final class, I can't make any mockup".
Fortunately there is very strong mockup framework called PowerMock and it allows make very interesting and helpful things in such hard cases. As instance, I needed to make a org.apache.bcel.generic.BranchHandle object for some test case but the class is both a final one and it has the private constructor.
public final class BranchHandle extends InstructionHandle { private BranchInstruction bi; private static BranchHandle bh_list; private BranchHandle(BranchInstruction i) { //compiled code throw new RuntimeException("Compiled Code"); } ... }
The class has the factory method
static final BranchHandle getBranchHandle(BranchInstruction i) { //compiled code throw new RuntimeException("Compiled Code"); }but the factory method is not accessible for me because it has the package view modifier.
Fortunately there is a very useful class org.powermock.reflect.Whitebox within the PowerMock framework that allows me to solve the problem
final BranchInstruction instructionInstance = instruction.getConstructor(InstructionHandle.class).newInstance(mockTarget); final BranchHandle branchHandle = Whitebox.invokeMethod(BranchHandle.class, "getBranchHandle", instructionInstance);As you can see in the code snippet above, the Whitebox utility class allows you to call a non-visible method of a class. Also the utility class allows you to create instance of the class without any call the private constructor through its newInstance() static method
Whitebox.newInstance(BranchInstruction.class);