Mockito

Powermock – Mockito Integration Example

Most of the mocking frameworks in Java, including Mockito, cannot mock static methods or final classes. If we come across a situation where we need to test these components, we won’t be able to unless we re-factor the code and make them testable. For example:

  1. Making private methods packaged or protected
  2. Avoiding static methods

But re-factoring at the cost of good design may not always be the right solution.
In such scenarios, it makes sense to use a testing framework like Powermock which allows us to mock even the static, final and private methods.
Good thing about Powermock is that it doesn’t re-invent the testing framework and in fact enhances the testing frameworks like Easymock and Mockito.

In this article, we will see an integration example of Powermock and Mockito but first let’s do the setup.

Below are my setup details:

1. Dependencies in pom.xml

Our dependencies consist of:

  1. junit
  2. mockito-core
  3. powermock-api-mockito
  4. powermock-module-junit4

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javacodegeeks.testng.maven</groupId>
	<artifactId>testngMaven</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-core</artifactId>
			<version>2.0.5-beta</version>
		</dependency>
		<dependency>
			<groupId>org.powermock</groupId>
			<artifactId>powermock-api-mockito</artifactId>
			<version>1.6.2</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.powermock</groupId>
			<artifactId>powermock-module-junit4</artifactId>
			<version>1.6.2</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

2. System Under Test (SUT)

Our system under test is a system called SomeSystem which owns some services. A service is defined by Service interface which has couple of methods getName() and start(). If the start of the service is successful it will return 1 else 0.

One can add a Service to the SomeSystem using add(service) method. Our SubSystem has a start() method which will start the services it contains. On start of each service, ServiceListener is notified of the success or failure of the service.

SomeSystem:

package com.javacodegeeks.mockito;

import java.util.ArrayList;
import java.util.List;

public class SomeSystem {
	private List services = new ArrayList();
	private ServiceListener serviceListener;
	private List events = new ArrayList();

	public void start() {
		for (Service service : services) {
			boolean success = startServiceStaticWay(service) > 0;
			notifyServiceListener(serviceListener, service, success);
			addEvent(service, success);
		}
	}
	
	private void addEvent(Service service, boolean success) {
		events.add(getEvent(service.getName(), success));
	}

	private String getEvent(String serviceName, boolean success) {
		return serviceName + (success ? "started" : "failed");
	}

	public static void notifyServiceListener(ServiceListener serviceListener,
			Service service, boolean success) {
		if (serviceListener != null) {
			if (success) {
				serviceListener.onSuccess(service);
			} else {
				serviceListener.onFailure(service);
			}
		}
	}

	public void add(Service someService) {
		services.add(someService);
	}

	public static int startServiceStaticWay(Service service) {
		int returnCode = service.start();
		return returnCode;
	}

	public void setServiceListener(ServiceListener serviceListener) {
		this.serviceListener = serviceListener;
	}	
	
	public List getEvents() {
		return events;
	}
}

Service:

package com.javacodegeeks.mockito;

public interface Service {	
	String getName();
	int start();
}

ServiceListener:

package com.javacodegeeks.mockito;

public interface ServiceListener {
	void onSuccess(Service service);
	void onFailure(Service service);
}

3. Integrate PowerMockito and Mockito

In setupMock(), we will set up our system. We will create mock objects for Service and ServiceListener using Mockito.mock. Both are interfaces and we don’t have the actual implementations ready.  Since SomeSystem is our SUT, we will create a spy object of it so that later we can stub some of its behavior.

Now let’s come to our first test startSystem:

  1. We will stub service.start() using PowerMockito so that it returns 1.
  2. Next, we start the system calling system.start()
  3. Finally, we will verify the behavior using Mockito’s verify() API
    Mockito.verify(serviceListener).onSuccess(service);

Notice that we stub using PowerMockito but verify using Mockito. This shows that Powermock doesn’t re-invent the wheel rather enhances the existing testing frameworks.

PowerMockitoIntegrationExample:

package com.javacodegeeks.mockito;

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.modules.junit4.PowerMockRunner;


@RunWith(PowerMockRunner.class)
public class PowerMockitoIntegrationExample {
	private Service service;
	private SomeSystem system;
	private ServiceListener serviceListener;

	@Before
	public void setupMock() {
		// Mock
		service = Mockito.mock(Service.class);
		serviceListener = Mockito.mock(ServiceListener.class);

		system = Mockito.spy(new SomeSystem());
		system.add(service);
		system.setServiceListener(serviceListener);
	}

	@Test
	public void startSystem() {
		// Stub using Mockito and PowerMockito
		p("Stub using PowerMockito. service.start() should return 1 as we want start of the service to be successful");
		PowerMockito.when(service.start()).thenReturn(1);

		// Run
		p("Start the system, should start the services in turn");
		system.start();		

		// Verify using Mockito	
		p("Verify using Mockito that service started successfuly");
		Mockito.verify(serviceListener).onSuccess(service);
		
		p("Verifed. Service started successfully");
	}

	private void p(String s) {
		System.out.println(s);
	}
}

Output:

Stub using PowerMockito. service.start() should return 1 as we want start of the service to be successful
Start the system, should start the services in turn
Verify using Mockito that service started successfuly
Verifed. Service started successfully

4. Mocking Static Method

The use of static methods goes against the Object Oriented concepts but in real world we still use a lot of static methods and there are times when it makes sense to use static methods. Nevertheless, the ability to mock static methods may come handy to us. In this example, we will stub a static non-void method.

In the beginning of test class you will notice @RunWith annotation that contains PowerMockRunner.class as value. This statement tells JUnit to execute the test using PowerMockRunner.

You may also see annotation @PrepareForTest which takes the class to be mocked. This is required when we want to mock final classes or methods which either final, private, static or native.

We will use PowerMockito.mockStatic statement which takes in the class to be mocked. It tells PowerMockito to mock all the static methods. We then stub the static method’s behavior.

For example, in stubStaticNonVoidMethod, we stub SomeSystem.startServiceStaticWay to return 1.

PowerMockito.when(SomeSystem.startServiceStaticWay(service)).thenReturn(1);

PowerMockitoStaticMethodExample:

package com.javacodegeeks.mockito;

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.modules.junit4.PowerMockRunner;


@RunWith(PowerMockRunner.class)
public class PowerMockitoStaticMethodExample {
	private Service service;
	private SomeSystem system;
	private ServiceListener serviceListener;

	@Before
	public void setupMock() {
		// Mock
		service = Mockito.mock(Service.class);
		serviceListener = Mockito.mock(ServiceListener.class);

		system = new SomeSystem();
		//system = Mockito.spy(new SomeSystem());
		system.add(service);
		system.setServiceListener(serviceListener);
	}

	@Test
	public void stubStaticNonVoidMethod() {
		// Stub static method startServiceStatic to start successfully
		p("Call mockStatic SomeSystem.class to enable static mocking");
		PowerMockito.mockStatic(SomeSystem.class);
		
		p("Stub static method startServiceStaticWay to return 1");
		PowerMockito.when(SomeSystem.startServiceStaticWay(service))
				.thenReturn(1);

		// Run
		p("Start the system, should start the services in turn");
		system.start();

		// Verify success
		p("Verify using Mockito that service started successfuly");
		Mockito.verify(serviceListener).onSuccess(service);

		// Stub static method startServiceStatic to fail
		p("Stub static method startServiceStaticWay to return 0");
		PowerMockito.when(SomeSystem.startServiceStaticWay(service))
				.thenReturn(0);

		// Run
		p("Start the system again");
		system.start();

		// Verify failure
		p("Verify using Mockito that service has failed");
		Mockito.verify(serviceListener).onFailure(service);
	}

	private void p(String s) {
		System.out.println(s);
	}
}

Output:

Call mockStatic SomeSystem.class to enable static mocking
Stub static method startServiceStaticWay to return 1
Start the system, should start the services in turn
Verify using Mockito that service started successfuly
Stub static method startServiceStaticWay to return 0
Start the system again
Verify using Mockito that service has failed

5. Mocking static void Method

In this example, we will mock a void static method. The first step would be to call PowerMockito.mockStatic similar to the static non-void method. Since a void method doesn’t return anything, the earlier way of mocking static methods won’t work here.

PowerMockito.doNothing().when(SomeSystem.class);

Next, we will stub the behavior. After stubbing, we will call the static method on which it applies.

SomeSystem.notifyServiceListener(serviceListener, service, true);

We will follow similar style for verifying a static void method.

PowerMockito.verifyStatic();
SomeSystem.startServiceStaticWay(service);

PowerMockitoStaticVoidMethodExample:

package com.javacodegeeks.mockito;

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;


@RunWith(PowerMockRunner.class)
public class PowerMockitoStaticVoidMethodExample {
	private Service service;
	private SomeSystem system;
	private ServiceListener serviceListener;

	@Before
	public void setupMock() {
		service = Mockito.mock(Service.class);
		serviceListener = Mockito.mock(ServiceListener.class);

		system = new SomeSystem();
		system.add(service);
		system.setServiceListener(serviceListener);
	}

	@PrepareForTest({ SomeSystem.class })
	@Test
	public void stubStaticVoidMethod() {		
		p("Call mockStatic SomeSystem.class to enable static mocking");
		PowerMockito.mockStatic(SomeSystem.class);
		
		p("Stub static void method SomeSystem.notifyServiceListener to do nothing");
		PowerMockito.doNothing().when(SomeSystem.class);
		SomeSystem.notifyServiceListener(serviceListener, service, true);
		
		p("Stub using PowerMockito. service.start() should return 1 as we want start of the service to be successful");
		PowerMockito.when(service.start()).thenReturn(1);		

		p("Start the system");
		system.start();

		p("Verify static method startServiceStaticWay(service) is called");
		PowerMockito.verifyStatic();
		SomeSystem.startServiceStaticWay(service);

		p("Verify serviceListener.onSuccess(service) is not called as notifyServiceListener is stubbed to do nothing");
		Mockito.verify(serviceListener, Mockito.never()).onSuccess(service);
	}

	private void p(String s) {
		System.out.println(s);
	}
}

Output:

Call mockStatic SomeSystem.class to enable static mocking
Stub static void method SomeSystem.notifyServiceListener to do nothing
Stub using PowerMockito. service.start() should return 1 as we want start of the service to be successful
Start the system
Verify static method startServiceStaticWay(service) is called
Verify serviceListener.onSuccess(service) is not called as notifyServiceListener is stubbed to do nothing

6. Subbing Private Method

Using PowerMockito we can stub as well as verify private methods. In this example, I will show you how to stub a private method.

Our private method addEvent adds an event to the list. The event will tell us know whether a service started successfully or failed. Since we can’t access the private method, we will have to pass the SUT object, private method name along with the method arguments to PowerMockito.doNothing().when() method.

In test case stubPrivateMethodAddEvent, we stub addEvent to do nothing.

PowerMockito.doNothing().when(system, "addEvent", service, true)

In test case stubPrivateMethodGetEventString, we stub getEvent to return some hardcoded string.

PowerMockito.when(system, "getEvent", serviceA, true).thenReturn(serviceA_is_successful);

PowerMockitoStubPrivateMethodExample:

package com.javacodegeeks.mockito;


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.junit.Assert;


@PrepareForTest({ SomeSystem.class })
@RunWith(PowerMockRunner.class)
public class PowerMockitoStubPrivateMethodExample {
	private Service service;
	private SomeSystem system;
	private ServiceListener serviceListener;

	@Before
	public void setupMock() {
		// Mock
		service = Mockito.mock(Service.class);
		serviceListener = Mockito.mock(ServiceListener.class);

		system = PowerMockito.spy(new SomeSystem());
		system.add(service);
		system.setServiceListener(serviceListener);
	}

	@Test
	public void stubPrivateMethodAddEvent() throws Exception {
		p("Stub using PowerMockito. service.start() should return 1 as we want start of the service to be successful");
		PowerMockito.when(service.start()).thenReturn(1);
		
		p("Stub service name to return serviceA");
		Mockito.when(service.getName()).thenReturn("serviceA");
		
		p("Stub private addEvent to do nothing");
		PowerMockito.doNothing().when(system, "addEvent", service, true);

		p("Start the system, should start the services in turn");
		system.start();

		p("Since we have stubbed addEvent, assert that system.getEvents() is empty");
		Assert.assertTrue(system.getEvents().isEmpty());
	}
	
	@Test
	public void stubPrivateMethodGetEventString() throws Exception {
		final String serviceA = "serviceA";
		final String serviceA_is_successful = serviceA + " is successful";
		p("Stub using PowerMockito. service.start() should return 1 as we want start of the service to be successful");
		PowerMockito.when(service.start()).thenReturn(1);
		
		p("Stub service name to return serviceA");
		Mockito.when(service.getName()).thenReturn(serviceA);
		
		p("Stub private addEvent to do nothing");
		PowerMockito.when(system, "getEvent", serviceA, true).thenReturn(serviceA_is_successful);

		p("Start the system, should start the services in turn");
		system.start();

		p("Since we have stubbed getEvent, assert that system.getEvents() contains the event string");
		Assert.assertTrue(!system.getEvents().isEmpty());
		Assert.assertEquals(serviceA_is_successful, system.getEvents().get(0));
		System.out.println(system.getEvents());
	}

	private void p(String s) {
		System.out.println(s);
	}
}

In stubPrivateMethodAddEvent, since we have stubbed addEvent to do nothing, no events will added to the list.

In stubPrivateMethodGetEventString, we confirm that the event string we have returned is found in the events.

Output:

Test stubPrivateMethodAddEvent:
Stub using PowerMockito. service.start() should return 1 as we want start of the service to be successful
Stub service name to return serviceA
Stub private addEvent to do nothing
Start the system, should start the services in turn
Since we have stubbed addEvent, assert that system.getEvents() is empty

Test stubPrivateMethodGetEventString:
Stub using PowerMockito. service.start() should return 1 as we want start of the service to be successful
Stub service name to return serviceA
Stub private addEvent to do nothing
Start the system, should start the services in turn
Since we have stubbed getEvent, assert that system.getEvents() contains the event string
[serviceA is successful]

7. Verifying Private Method

Verification is similar to stubbing and PowerMockito allows us to verify even the private methods. The name of the method is passed to the PowerMockito.verifyPrivate along with its arguments.

PowerMockito.verifyPrivate(system).invoke("addEvent", new Object[] { service, true });

PowerMockitoVerifyPrivateMethodExample:

package com.javacodegeeks.mockito;


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.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
public class PowerMockitoVerifyPrivateMethodExample {
	private Service service;
	private SomeSystem system;
	private ServiceListener serviceListener;

	@Before
	public void setupMock() {
		// Mock
		service = Mockito.mock(Service.class);
		serviceListener = Mockito.mock(ServiceListener.class);

		system = Mockito.spy(new SomeSystem());
		system.add(service);
		system.setServiceListener(serviceListener);
	}

	@Test
	public void verifyPrivateMethods() throws Exception {
		p("Stub using PowerMockito. service.start() should return 1 as we want start of the service to be successful");
		PowerMockito.when(service.start()).thenReturn(1);
		
		p("Stub service name to return serviceA");
		Mockito.when(service.getName()).thenReturn("serviceA");

		p("Start the system, should start the services in turn");
		system.start();

		p("Verify private method addEvent(service, true) is called");
		PowerMockito.verifyPrivate(system).invoke("addEvent",
				new Object[] { service, true });
		p("Verified private method is called");
	}
	
	private void p(String s) {
		System.out.println(s);
	}
}

Output:

Stub using PowerMockito. service.start() should return 1 as we want start of the service to be successful
Stub service name to return serviceA
Start the system, should start the services in turn
Verify private method addEvent(service, true) is called
Verified private method is called

8. Download Source Code

This example was about PowerMockito and Mockito integration.

Download
You can download the full source code of this example here: powerMockitoIntegration.zip

Ram Mokkapaty

Ram holds a master's degree in Machine Design from IT B.H.U. His expertise lies in test driven development and re-factoring. He is passionate about open source technologies and actively blogs on various java and open-source technologies like spring. He works as a principal Engineer in the logistics domain.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
tukaram
tukaram
6 years ago

Getting – NoClassDefFoundError: org/junit/internal/runners/TestClass
please help.

Anand
Anand
2 years ago

How you are saving the list of service because Service is an interface not model class

Back to top button