Thursday, August 16, 2018

JUnit Test - Setting Private Field Using PowerMockito's Whitebox

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.







3 comments: