Update:
Some 10 years later perhaps the best way to test a private method, or any inaccessible member, is via @Jailbreak
from the Manifold framework.
@Jailbreak Foo foo = new Foo();
// Direct, *type-safe* access to *all* foo's members
foo.privateMethod(x, y, z);
foo.privateField = value;
This way your code remains type-safe and readable. No design compromises, no overexposing methods and fields for the sake of tests.
If you have somewhat of a legacy Java application, and you're not allowed to change the visibility of your methods, the best way to test private methods is to use reflection.
Internally we're using helpers to get/set private
and private static
variables as well as invoke private
and private static
methods. The following patterns will let you do pretty much anything related to the private methods and fields. Of course, you can't change private static final
variables through reflection.
Method method = TargetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);
And for fields:
Field field = TargetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
Notes:
1. TargetClass.getDeclaredMethod(methodName, argClasses)
lets you look into private
methods. The same thing applies for
getDeclaredField
.
2. The setAccessible(true)
is required to play around with privates.
It depends on the JUnit version and what assert libraries you use.
The original answer for JUnit <= 4.12
was:
@Test(expected = IndexOutOfBoundsException.class)
public void testIndexOutOfBoundsException() {
ArrayList emptyList = new ArrayList();
Object o = emptyList.get(0);
}
Though answer https://stackoverflow.com/a/31826781/2986984 has more options for JUnit <= 4.12.
Reference :
Best Solution
The following suggestion let's you test abstract classes without creating a "real" subclass - the Mock is the subclass.
use
Mockito.mock(My.class, Mockito.CALLS_REAL_METHODS)
, then mock any abstract methods that are invoked.Example:
Note: The beauty of this solution is that you do not have to implement the abstract methods, as long as they are never invoked.
In my honest opinion, this is neater than using a spy, since a spy requires an instance, which means you have to create an instantiatable subclass of your abstract class.