Dziś krótko. Sytuacja jest prosta, mamy do zamockowania prywatną metodę w singletonie. W uproszczeniu może wyglądać to tak:

public class Singleton {

	private static final Singleton INSTANCE = new Singleton();

	private Singleton() {

	}

	public static Singleton get() {
		return INSTANCE;
	}

	public String doPublic(String in) {
		return doPrivate(in);
	}

	private String doPrivate(String in) {
		return "fromPrivate" + in;
	}

}

Chcemy zamockować metodę doPrivate, aby zwracała zupełnie coś innego. Wykorzystamy do tego Mockito w połączeniu z PowerMock oraz oczywiście JUnit. Zależności dla mavena:

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.10</version>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>org.powermock</groupId>
	<artifactId>powermock-module-junit4</artifactId>
	<version>1.4.12</version>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>org.powermock</groupId>
	<artifactId>powermock-api-mockito</artifactId>
	<version>1.4.12</version>
	<scope>test</scope>
</dependency>

Mockito jest w zależnościach PowerMock, więc zostanie zaciągnięte automatycznie.

Poniżej rozwiązanie naszego problemu:

import org.junit.Assert;
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)
@PrepareForTest({Singleton.class})
public class SingletonTest {

	private Singleton singleton;

	@Before
	public void prepareTest() throws Exception {
		singleton = PowerMockito.spy(Singleton.get());
		PowerMockito.doReturn("fromTest").when(singleton, "doPrivate", Mockito.anyString());
	}

	@Test
	public void test() throws Exception {
		String res = singleton.doPublic("qwerty");
		Assert.assertEquals("fromTest", res);
	}

}

Ważny jest sposób w jaki tworzymy mock’a naszej klasy, patrz linia 18 powyżej. Pamiętać należy również, aby wszystkie klasy, które będą mock’owane przez PowerMock wskazać w adnotacji @PrepareForTest.

Kombinacja JUnit + Mockito + PowerMock nadaje się świetnie do pisania testów jednostkowych.