Over a million developers have joined DZone.

Mock Final Method

· DevOps Zone

Discover how to optimize your DevOps workflows with our cloud-based automated testing infrastructure, brought to you in partnership with Sauce Labs

Foreword

If you already read some other blog post about unusual mocking, you can skip prelude via this link.

I was asked to put together examples how to mock Java constructs well know for their testability issues:

I am calling these techniques unusual mocking. I was worried that such examples without any guidance can be widely used by teammates not deeply experienced in mocking frameworks.

Developers practicing TDD or BDD should be aware of testability problems behind these constructs and try to avoid them when designing their tests and modules. That is the reason why you probably wouldn't be facing such unusual mocking often on project using these great programming methodologies.

But sometimes you have to extend or maintain legacy codebase that usually contains low cohesive classes. In most cases there isn't time in current hectic agile world to make such class easy to unit test standard way. When you are trying to unit test such class you often realize that unusual mocking is needed.

That is why I decided to create and share refactoring considerations alongside with examples and workarounds for unusual mocking. Examples are using Mockito and PowerMock mocking frameworks and TestNG unit testing framework.

Mock final method

Refactoring considerations

Change method to non-final (remove final keyword) and test it standard way. This is technique I use always when I can change code of final method.

Usage of PowerMock

Before usage of this example, please carefully consider if it is worth to bring bytecode  manipulation risks into your project. They are gathered in this blog post. In my opinion it should be used only in very rare and non-avoidable cases.

Test shows how to mock final method by PowerMock framework. Example covers:

  1. Mocking of final method with return value
  2. Mocking of final void method
  3. Verifying of final method calls

Class with final methods:

public class Bike {
	public final void shiftGear(boolean easier) {
		throw new UnsupportedOperationException("Fail if not mocked! [easier="
				+ easier + "]");
	}

	public final int getGear() {
		throw new UnsupportedOperationException("Fail if not mocked!");
	}
}

Class under test:

public class Rider {
	private Bike bike;

	public Rider(Bike bike) {
		this.bike = bike;
	}

	public int prepareForUphill() {
		int gear = bike.getGear();
		for (int idx = 0; idx < 2; idx++) {
			bike.shiftGear(true);
			gear++;
		}
		return gear;
	}
}

Test:

@PrepareForTest(Bike.class)
public class RiderTest extends PowerMockTestCase {
	private static final int TESTING_INITIAL_GEAR = 2;

	@Test
	public void testShiftGear() {
		Bike mock = PowerMockito.mock(Bike.class);

		Rider rider = new Rider(mock);
		Mockito.when(mock.getGear()).thenReturn(TESTING_INITIAL_GEAR);

		// invoke testing method
		int actualGear = rider.prepareForUphill();

		Assert.assertEquals(actualGear, TESTING_INITIAL_GEAR + 2);
		Mockito.verify(mock, Mockito.times(2)).shiftGear(true);
	}
}

Links

Source code can be downloaded from Github.

Other unusual mocking examples:

Download “The DevOps Journey - From Waterfall to Continuous Delivery” to learn learn about the importance of integrating automated testing into the DevOps workflow, brought to you in partnership with Sauce Labs.

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}