Unit Testing Your Methods By Mocking Private Methods With JMockit Library

So you wrote some public methods which in turn call other private methods and you are asked to write junits for those public methods. But your private method calls do stuffs that you don’t want to test (for example, they might be trying to connect to a database). How would you then write a unit test for you public methods at the same time avoid stuffs that are done in the private methods?

In this tutorial, I will show you how you can use JMockit to mock the private methods. The main magic is, when you are mocking a private method, do not write the access modifier (private).

So instead of trying to mock the method the following way,

@Mock
private boolean doPrivateStuff() {
}

Use this one instead – no private:

@Mock
boolean doPrivateStuff() {
}

Here is the complete code.

package com.kushal.tools;

import mockit.Mock;
import mockit.MockUp;

import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * This class shows you how to Mock a private method.
 * @author Kushal Paudyal
 * www.sanjaal.com/java
 * www.icodejava.com
 *
 */

public class PrivateMethodMockTest {

    SomeClass object;
    @Before
    public void setup() {
        object = new SomeClass();
    }
    @SuppressWarnings("unused")
    @Test
    public void test_doPublicStuff_with_mocked_private_method() {
        new MockUp<SomeClass>() {
            @Mock
            boolean doPrivateStuff() {
                System.out.println("This is a mocked private method of class - SomeClass");
                
                /**
                 * Returning false from a mocked method
                 */
                return false; 
            }
        };
        
        boolean result = object.doPublicStuff();
        
        Assert.assertThat(result, CoreMatchers.is(false));
    }
    
    @Test
    public void test_doPublicStuff_with_no_mocking() {
        
        boolean result = object.doPublicStuff();
        
        Assert.assertThat(result, CoreMatchers.is(true));
    }
}

/**
 * This is a demo class whose public method will be tested.
 * Private method can be mocked.
 */
class SomeClass {
    
    public boolean doPublicStuff() {

        System.out.println("Inside doPublicStuff");
        /**
         * Call doPrivateStuff() method from this public method
         */
        return doPrivateStuff();
    }
    
    /**
     * Defining a private method that we want to mock with JMockit
     */
    private boolean doPrivateStuff() {
        System.out.println("Doing Some Private Stuff from Class - SomeClass");
        
        /**
         * Returning true from a real  method.
         */
        return true;
    }
    
}

Tagged , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *