Testing Static Members and Methods
From Software By Jeff
It's very difficult to test static members fields. Easy to test methods, but hard to test the fields.
Thankfully, Java provides Reflection, which allows us to access any of an object's members, no matter what the suggested accessor.
Let's make a simple test that tries to get class' private static memeber, and look at it with Reflection interjected.
public void testSomething(){
Field field = SomeClass.class.getDeclaredField("someField");
boolean wasAccessible = field.isAccessible();
if (!wasAccessible)
field.setAccessible(true);
Object object = field.get(null);
if (!wasAccessible)
field.setAccessible(false);
}
This basic test, which really only tests that Reflection can find the member and retreive a value for us, shows us what we need to do with to get the private static member. The test is broken in four bits.
The first uses getDeclaredField() to extract the field from SomeClass. We need to provide the class SomeClass represents; without it, compile time errors occur.
If the field exists, the test moves on to where we check to see if it's visible. Visibility is determined by the field's accessor, and is visible if it's assigned public (in which case we don't need to use Reflection), or package (and we're in the same package--again, Reflection is not required). If the accessor is package (and we're not in the same package), protected (and we're not extending that class), or private (no matter what we want), it will be unavailable, and we'll tell Reflection to let us at it.
The next bit pulls the value from the static member and returns it wrapped in a Java Object. This means we can access primatives, too, like int, long, and boolean, and Reflection will wrap them to the appropriate class, like Integer, Long, and Boolean, respectively. We can hand the field.get() a null value because we're working with a static member field. If the field is not static, Reflection will complain and we'll stop the test here.
At this point, we should do whatever it is we want to do. Compare the value with an expected value, do something to change it, or whatever. We can also use the Relflection set(Object, Object) to put a value in the field, if we want to configure our static in a particular way.
Finally, we're polite and return the field to the appropriate access. Basically, if we futzed with it, we futz it back the way it was. This protects future tests from inappropraite access to the field.