Hi, I'm John 👋

Knobs 🎛️ Syntax ⌨️

Beginners guide to using Mockito and PowerMockito to unit test Java

Background

Lately, I have been writing Java at work, and it is something I haven’t done in years. I have been completely oblivious to the current ecosystem.

When it came time to write some unit tests for the code I was working on I wasn’t given a ton of direction. Our team had classically created overriden classes to perform stubbing. I wasn’t 100% pleased with this so I decided to explore what was out there.

Thus I stumbled across Mockito and PowerMockito and was very happy with the results.

Setup

I have been using Gradle for building at work so that’s what I’m going to use in my example. We need to add these two lines to our dependencies:

testCompile group: 'org.mockito', name: 'mockito-all', version: '1.9.5'
testCompile "org.powermock:powermock-mockito-release-full:1.6.1"

After we refresh gradle, it will pull these dependancies down for testing.

Example Classes

I have a

View this post on Instagram

A post shared by Interpolate (@jmullins480) on

so enjoy my puppy themed source code ;)

Human.java

public class Human {
    public String name;
    public Puppy puppy;

    public Human(String name) {
        this.name = name;
    }

    public void buyPuppy(String name){
        puppy = Puppy.createPuppy(name, this);
    }

    public void walkWithPuppy() {
        puppy.goOnWalk(15);
    }

    public static void main(String[] args) {
        Human john = new Human("John");
        john.buyPuppy("Gatsby");
        john.puppy.performPuppyTasks();
        john.walkWithPuppy();
    }

    public void isSoHappy() {
        System.out.println("Yay!");
    }
}

Puppy.java

import java.util.Random;

public class Puppy {
    private final String name;
    public Human owner;
    private int energyLevel;
    private Random puppyRandomness;

    public Puppy(String name, Human owner){
        this.name = name;
        this.owner = owner;
        energyLevel = 100;
        puppyRandomness = new Random();
    }

    public static Puppy createPuppy(String name, Human human) {
        human.isSoHappy();
        return new Puppy(name, human);
    }

    public void chaseTail(){
        bark();
        energyLevel -= getRandomInt(10);
    }
    public void bark(){
        System.out.println("WOOF!");
    }

    public void goOnWalk(int length){
        performBusiness();
        energyLevel -= length;
        wipeOffFeet();
    }

    public void wipeOffFeet(){
        System.out.println("Paws on fleek");
    }

    private void performBusiness() {
        System.out.println("When you gotta go you gotta go...");
    }

    public void performPuppyTasks(){
        eat();
        sleep();
        play();
    }

    private void eat(){
        energyLevel+= getRandomInt(10);
    }

    private void sleep() {
        energyLevel+= getRandomInt(10);
    }

    private void play() {
        energyLevel-= getRandomInt(10);
    }

    private int getRandomInt(int bounds){
        return puppyRandomness.nextInt(bounds);
    }

    public String getName() {
        return name;
    }
}

The Test Class

This is the test class. Notice how it extends PowerMockTestCase and how we annotate it with:

@PrepareForTest({Puppy.class})
@RunWith(PowerMockRunner.class)

PuppyTest.java

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.testng.PowerMockTestCase;
import org.powermock.reflect.Whitebox;

import static org.mockito.Mockito.times;

@PrepareForTest({Puppy.class})
@RunWith(PowerMockRunner.class)
public class PuppyTest extends PowerMockTestCase {

    @Test
    public void testCreatePuppy() throws Exception {
        //Mocking
        Human human = Mockito.mock(Human.class);
        Puppy puppy = Puppy.createPuppy("Woofer", human);
        assert(puppy != null);
        assert(puppy.getName().equals("Woofer"));
        //Verifying
        Mockito.verify(human, times(1)).isSoHappy();

    }

    @Test
    public void testChaseTail() throws Exception {
        Human human = Mockito.mock(Human.class);
        //Spying
        Puppy puppy = Mockito.spy(new Puppy("Woofer", human));
        Mockito.doNothing().when(puppy).bark();
        puppy.chaseTail();
        Mockito.verify(puppy, times(1)).bark();
    }

    @Test
    public void testGoOnWalk() throws Exception {
        Human human = Mockito.mock(Human.class);
        //Power Spying
        Puppy puppy = PowerMockito.spy(new Puppy("Woofer", human));
        PowerMockito.doNothing().when(puppy, "performBusiness");
        //Can combine regular and power
        Mockito.doNothing().when(puppy).wipeOffFeet();
        puppy.goOnWalk(15);
        Mockito.verify(puppy, times(1)).wipeOffFeet();
    }

    @Test
    public void testBuyPuppy() throws Exception {
        //Mocking static
        PowerMockito.mockStatic(Puppy.class);
        Human human = new Human("John");
        Puppy puppy = Mockito.mock(Puppy.class);
        //Static mocking and matchers
        PowerMockito.when(Puppy.createPuppy(Mockito.eq("Woofer"), Mockito.any(Human.class))).thenReturn(puppy);
        human.buyPuppy("Woofer");
        assert(human.puppy != null);
    }

    @Test
    public void testEat() throws Exception {
        Human human = Mockito.mock(Human.class);
        Puppy puppy = PowerMockito.spy(new Puppy("Woofer",human));
        //Get private variables
        int energy = Whitebox.getInternalState(puppy, "energyLevel");
        //Call private methods
        Whitebox.invokeMethod(puppy, "eat");
        int energyAfterwards = Whitebox.getInternalState(puppy, "energyLevel");
        System.out.println(energy + " > " + energyAfterwards);
        assert(energy <= energyAfterwards);
    }
}

Mocking

Mocking is something we do to classes to make our life simplier while unit testing. Essentially, it turns off all the functionality of a class. This is useful when we want to test methods that call functionality on other objects.

Here is a test that uses mocking.

    @Test
    public void testCreatePuppy() throws Exception {
        //Mocking
        Human human = Mockito.mock(Human.class);
        Puppy puppy = Puppy.createPuppy("Woofer", human);
        assert(puppy != null);
        assert(puppy.getName().equals("Woofer"));
        //Verifying
        Mockito.verify(human, times(1)).isSoHappy();
    }
On line 4 we use Mockito to mock a human class. This prevents all of Human’s methods from doing anything, but more specifically prevents isSoHappy() from being called in Puppy.createPuppy().

Notice that we also use Mockito.verify() to verify the method was still called only once even though it does not actually do anything.

Spying

Lets suppose we want a class to do everything it would normally do EXCEPT for one or more specific methods. This is where spying and PowerMockito comes into place. We can spy on an object and specify when methods are called to do other things.

Here is a test using spying.

    @Test
    public void testChaseTail() throws Exception {
        Human human = Mockito.mock(Human.class);
        //Spying
        Puppy puppy = Mockito.spy(new Puppy("Woofer", human));
        Mockito.doNothing().when(puppy).bark();
        puppy.chaseTail();
        Mockito.verify(puppy, times(1)).bark();
    }
Notice with spying we are actually creating an object. chaseTail() only reduces the dogs energy (which is a private variable uh oh!) and barks(). We don’t want bark to do anything, but reducing the energy is fine. This is why we used Mockito to doNothing() when puppy bark()’s.

Again, notice that we can still verify that bark was called even though we stubbed it out.

Power spying to stub private methods

Lets suppose we want to spy on an object but we want a private method to do something else. PowerMockito has you covered!

    @Test
    public void testGoOnWalk() throws Exception {
        Human human = Mockito.mock(Human.class);
        //Power Spying
        Puppy puppy = PowerMockito.spy(new Puppy("Woofer", human));
        PowerMockito.doNothing().when(puppy, "performBusiness");
        //Can combine regular and power
        Mockito.doNothing().when(puppy).wipeOffFeet();
        puppy.goOnWalk(15);
        Mockito.verify(puppy, times(1)).wipeOffFeet();
    }
We tell PowerMockito to doNothing() when puppy calls “performBusiness” on line 6. If we wanted to, we could specify params after that (like PowerMockito.doNothing().when(puppy, “performBusiness”, Mockito.any(Whatever.class))

Notice how on line 8 we are mixing Mockito with PowerMockito. Not only can we do this, it is encouraged. PowerMockito is a permgen memory hog and creates tons of classes. Whenever we can use Mockito over PowerMockito, we should!

Stubbing static methods

Lets suppose you have a class with a static method and we want to stub out its behaviour. PowerMockito has a way to do this.

    @Test
    public void testBuyPuppy() throws Exception {
        //Mocking static
        PowerMockito.mockStatic(Puppy.class);
        Human human = new Human("John");
        Puppy puppy = Mockito.mock(Puppy.class);
        //Static mocking and matchers
        PowerMockito.when(Puppy.createPuppy(Mockito.eq("Woofer"), Mockito.any(Human.class))).thenReturn(puppy);
        human.buyPuppy("Gatsby");
        assert(human.puppy != null);
    }
We specify PowerMockito.mockStatic on the class we want to stub our static method. On line 8 we stub it out like any other method.

Also notice we are specifying that we need the first argument to be “Woofer” but we will accept any Human.class for the second arguement.

Other WhiteBox fun

If you need to access any private members or invoke private methods we can use WhiteBox which is provided with PowerMockito.

    @Test
    public void testEat() throws Exception {
        Human human = Mockito.mock(Human.class);
        Puppy puppy = PowerMockito.spy(new Puppy("Woofer",human));
        //Get private variables
        int energy = Whitebox.getInternalState(puppy, "energyLevel");
        //Call private methods
        Whitebox.invokeMethod(puppy, "eat");
        int energyAfterwards = Whitebox.getInternalState(puppy, "energyLevel");
        System.out.println(energy + " > " + energyAfterwards);
        assert(energy <= energyAfterwards);
    }
On line 6 we are using getInternalState to get the value of our puppy’s private variable energyLevel.

On line 8 we invoke the private method “eat”.

We could technically set a private variable via setInternalState(object, “variable”, value) or call a private method with parameters via invokeMethod(object, “privateMethod”, parameter).

Conclusion

So far we have mocked and stubbed via Mockito, mocked and stubbed private methods via PowerMockito, and got into all sorts of trouble with Whitebox. If you are feeling powerful and a bit naughty, I think you are doing it right. You can over abuse these libraries and make tests useless, or you can remove the bare minimum to get appropriate code coverage.

I had a blast learning all of this and I hope you do too. Stay frosty, and try to enjoy unit testing ;)