Java

Partial mocking with PowerMock

I love PowerMock! For those who don't know it, quoting their site, "PowerMock is a Java framework that allows you to unit test code normally regarded as untestable". While not one of its unique selling points, because EasyMock allows you to do basically the same, I'll show an example here of partially mocking a class in PowerMock.

I love PowerMock! For those who don’t know it, quoting their site, “PowerMock is a Java framework that allows you to unit test code normally regarded as untestable”.

While not one of its unique selling points, because EasyMock allows you to do basically the same, here’s an example of partially mocking a class in PowerMock.

Given class CustomerService:

class CustomerService {

	public void add(Customer customer) {
		if (someCondition) {
			subscribeToNewsletter(customer);
		}
	}

	void subscribeToNewsletter(Customer customer) {
		// ...subscribing stuff
	}
}

So you want to test the add() method for actually invoking subscribeToNewsletter() and do NOT want to execute the logic from subscribeToNewsletter() in this test – e.g. since you’re already unit testing subscribeToNewsletter() somewhere else.

Then you create a PARTIAL mock of CustomerService, giving a list of methods you want to mock.

CustomerService customerService = PowerMock.createPartialMock(CustomerService.class, "subscribeToNewsletter");
customerService.subscribeToNewsletter(anyObject(Customer.class));

replayAll();

customerService.add(createMock(Customer.class));

So add() within the CustomerService mock is the REAL thing you want to test and for the method subscribeToNewsletter() you now can write an expectation as usual.

Disclaimer:

  • Mocking partially like this only works with PUBLIC or DEFAULT methods. So for this one, I actually had to change subscribeToNewsletter() from PRIVATE to DEFAULT visibility to make it testable – which possible might not be desirable in all cases.
  • Using a string “subscribeToNewsletter” which matches an actual method name is not very refactoring safe. Preferable you should at least a constant to discriminate from being any ordinary string. Anyway, your unit test will break sooner or later anyway if this method changes name – and you’ll know 🙂

For further reading, where PowerMock really excels is mocking of static methods and private methods.