Je ne sais pas comment se moquer d'une classe singleton enum.
public enum SingletonObject{
INSTANCE;
private int num;
protected setNum(int num) {
this.num = num;
}
public int getNum() {
return num;
}
Je voudrais stub getNum () dans l'exemple ci-dessus, mais je ne peux pas comprendre comment se moquer de la classe SingletonObject réelle. Je pensais que l'utilisation de Powermock pour préparer le test aiderait, car les énumérations sont intrinsèquement finales.
//... rest of test code
@Test
public void test() {
PowerMockito.mock(SingletonObject.class);
when(SingletonObject.INSTANCE.getNum()).thenReturn(1); //does not work
}
Cela utilise PowerMockMockito 1.4.10 et Mockito 1.8.5.
Si vous voulez supprimer ce que INSTANCE renvoie, vous pouvez le faire mais c'est un peu méchant (en utilisant la réflexion et la manipulation de bytecode). J'ai créé et testé un projet simple avec trois classes en utilisant le PowerMock 1.4.12/Mockito 1.9.0. Toutes les classes étaient dans le même package.
public enum SingletonObject {
INSTANCE;
private int num;
protected void setNum(int num) {
this.num = num;
}
public int getNum() {
return num;
}
}
public class SingletonConsumer {
public String consumeSingletonObject() {
return String.valueOf(SingletonObject.INSTANCE.getNum());
}
}
import static org.junit.Assert.*;
import static org.powermock.api.mockito.PowerMockito.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
@RunWith(PowerMockRunner.class)
@PrepareForTest({SingletonObject.class})
public class SingletonConsumerTest {
@Test
public void testConsumeSingletonObject() throws Exception {
SingletonObject mockInstance = mock(SingletonObject.class);
Whitebox.setInternalState(SingletonObject.class, "INSTANCE", mockInstance);
when(mockInstance.getNum()).thenReturn(42);
assertEquals("42", new SingletonConsumer().consumeSingletonObject());
}
}
L'appel au Whitebox.setInternalState
remplace INSTANCE
par un objet factice que vous pouvez manipuler dans votre test.
Avoir une interface avec les méthodes que vous avez l'intention de simuler
public interface SingletonInterface {
int getNum();
}
Laissez l'énumération implémenter l'interface
public enum SingletonObject implements SingletonInterface {
INSTANCE;
private int num;
protected void setNum(int num) {
this.num = num;
}
@Override
public int getNum() {
return num;
}
}
Se moquer de l'interface
@Test
public void test() {
SingletonInterface singleton = Mockito.mock(SingletonInterface.class);
when(singleton.getNum()).thenReturn(1); //does work
}