PowerMock : How to test a private method

· ☕ 4 min read · ✍️ Dinesh

“I HAVE THE POWER!!” – I had this feeling a few days ago. I will be honest that at work I do not get time to write unit test cases for each and every piece of code that I write. Often when I do have time, I make an effort to write test cases even for the trivial piece of code blocks such as — Check if properties file is present.

I was working on new code where I had the luxury to write the code in peace (a rarity at my work place where every project is like a fire drill). While writing test cases I came across a situation where I had a class with two methods:

1
2
3
4
5

public void my_public_method()

private void my_private_method()

I wanted to write test cases for both the method. However Junit would not allow me to write a test case for a private method. I searched over internet forums and every one suggested that I use Java Reflection API  to write my test cases or make my private method public, which I did not want to do.

That’s when POWERMOCK steps in and in a tiny little section of its documentation I noticed a piece of “**WhiteboxImpl” ** class which can help me test private methods.

So that’s what I am going to demonstrate in this tutorial.

STEP 1: Add Maven jar files

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

<properties>

<relative.path>relative/svn/path</relative.path>

<powermock.version>1.6.2</powermock.version>

</properties>

<dependencies>

&#8230;&#8230;..

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.11</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.powermock</groupId>

<artifactId>powermock-module-junit4</artifactId>

<version>${powermock.version}</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.powermock</groupId>

<artifactId>powermock-api-easymock</artifactId>

<version>${powermock.version}</version>

<scope>test</scope>

</dependency>

<dependencies>

STEP 2: Create a class MyClass.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class MyClass {

//PUBLIC METHOD

public String my _public _method(){

String msg="This is my PUBLIC method";

System.out.println(msg);

return msg;

}

//PRIVATE METHOD

private String my _private _method(){

String msg="This is my PRIVATE method";

System.out.println(msg);

return msg;

}

}

STEP 3: Write a test case for public method : my _public _method

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

import org.junit.Assert;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.powermock.core.classloader.annotations.PrepareForTest;

import org.powermock.modules.junit4.PowerMockRunner;

import org.powermock.reflect.internal.WhiteboxImpl;

@RunWith(PowerMockRunner.class)

@PrepareForTest(MyClass.class)

public class MyClassTest {

final String publicMsg = "This is my PUBLIC method";

final String privateMsg = "This is my PRIVATE method";

@Test

public void testMy _public _method() throws Exception {

MyClass myClass = new MyClass();

String msg=myClass.my _public _method();

Assert.assertEquals(publicMsg,msg);

}

}

As you can see above that there is no issue with calling a public method and it will run successfully but when you try and call the private method, the code will show error that private method is not visible.

STEP 4: Use PowerMock’s WhiteboxImpl class to test a private method.

Before you do anything you need to make sure that you added Powermock annotations correctly.

  • Add these two annotations to your class.

[java]

@RunWith(PowerMockRunner.class)

@PrepareForTest(MyClass.class)

[/java]

  • Write the code to test private method.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

@Test

public void testMy _private _method() throws Exception {

MyClass myClass = new MyClass();

String msg= WhiteboxImpl.invokeMethod(myClass, "my _private _method");

Assert.assertEquals(privateMsg,msg);

}

The syntax is pretty simple WhiteboxImpl.invokeMethod(, “,input param1, input param2,…);

The WhiteBoxImpl class actually uses “Java Reflection API” in the background to make a call, but for the lazy coders like me, who do not want to write Reflection API(Read hate Reflection API), the WhiteBoxImpl class is a small piece of coding heaven.

Now run the test class and you will see that test cases have passed.

~Ciao –Repeat the mantra – “I HAVE THE POWER{MOCK}!!!”

Share this post
Support the author with

Dinesh Arora
WRITTEN BY
Dinesh
Developer