Introduction
There might be a case when you need to write a JUnit test for a class method which depends upon some
private field that is in turn set during the deployment from some disk file or database or Network source or any other source.
Now when you write the JUnit test for that method, the field is not set. You cannot set it because it is a private field. You could have have a
setter method, but obviously you are not going to create a setter method just for the sake of testing.
Solution Using PowerMockito - Whitebox
Such a case can be easily handled using PowerMockito. PowerMockito framework gives us the leverage to set the private fields with some mocked values.
Consider the following class StockCache:
Here we try to write JUnit test for the method
getStockDetail(). This method depends upon the private field
cachedStocks. This field is in turn set by the method
initializeCachedStocks(). Now to test the method
getStockDetail(), the private field needs to be set. We could have called the method
initializeCachedStocks() to set the field.
But the question is, do we want to call this method during a test? Well the answer depends upon the nature of this method. If it simply reads some static data and sets the field, then there is no problem executing it during the test. However, if it needs to access some network location or read database, then we don't want to execute it.
At such instance, we want to set some mocked value to this field. We could have created a
setter method. However, as already mentioned above, it is not good idea to create a setter method just for testing.
We can set the private field using
org.powermock.reflect.Whitebox.setInternalState method.
Whitebox.setInternalState(<StockCacheInstance>, <private_field_name>, cachedStock);
Complete Implementation
Following is the complete implementation for testing the method.