My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
MockSystem  
Updated Oct 14, 2010 by johan.ha...@gmail.com

Mocking system classes

Note: The same technique applies to the Mocktio API extension as well although all examples shown here are made with the EasyMock API extension.

Quick summary

  1. Use the @RunWith(PowerMockRunner.class) annotation at the class-level of the test case.
  2. Use the @PrepareForTest({ClassThatCallsTheSystemClass.class}) annotation at the class-level of the test case.
  3. Use mockStatic(SystemClass.class) to mock the system class then setup the expectations as normally.
  4. EasyMock only: Use PowerMock.replayAll() to change to replay mode.
  5. EasyMock only: Use PowerMock.verifyAll() to change to verify mode.

Example

PowerMock 1.2.5 and above supports mocking static methods in Java system classes such as those located in java.lang and java.net etc. This works without modifying your JVM or IDE settings! The way to go about mocking these classes are a bit different than usual though. Normally you would prepare the class that contains the static methods (let's call it X) you like to mock but because it's impossible for PowerMock to prepare a system class for testing another approach has to be taken. So instead of preparing X you prepare the class that calls the static methods in X! Let's look at a simple example:

public class SystemClassUser {

	public String performEncode() throws UnsupportedEncodingException {
		return URLEncoder.encode("string", "enc");
	}
}

Here we'd like to mock the static method call to java.net.URLEncoder#encode(..) which is normally not possible. Since the URLEncoder class is a system class we should prepare the SystemClassUser for test since this is the class calling the encode method of the URLEncoder. I.e.

@RunWith(PowerMockRunner.class)
@PrepareForTest( { SystemClassUser.class })
public class SystemClassUserTest {

	@Test
	public void assertThatMockingOfNonFinalSystemClassesWorks() throws Exception {
		mockStatic(URLEncoder.class);

		expect(URLEncoder.encode("string", "enc")).andReturn("something");
		replayAll();

		assertEquals("something", new SystemClassUser().performEncode());

		verifyAll();
	}
}

References

Comment by jamesfid...@gmail.com, Mar 5, 2012

When using EcmEmma? in Eclipse any class in @PrepareForTest?( { }) does not show any code coverage (I'm assuming because PowerMock? makes it Proxy object and the code coverage tool fails to notice the orginal class being called).

This means that I can't use the above technique for classes that call System classes that I want to calculate code coverage on.

I'm not sure if this is an issue with PowerMock? or with EclEmma?.


Sign in to add a comment
Powered by Google Project Hosting