power mock method java enums singleton mockito powermock

java - method - ¿Cómo burlarse de una clase enlet singleton utilizando Mockito/Powermock?



powermock vs mockito (1)

No estoy seguro de cómo burlarse de una clase de singleton enumeración.

public enum SingletonObject{ INSTANCE; private int num; protected setNum(int num) { this.num = num; } public int getNum() { return num; }

Me gustaría resaltar getNum () en el ejemplo anterior, pero no puedo imaginar cómo burlarme de la clase SingletonObject real. Pensé que usar Powermock para preparar la prueba ayudaría, ya que las enumeraciones son inherentemente finales.

//... rest of test code @Test public void test() { PowerMockito.mock(SingletonObject.class); when(SingletonObject.INSTANCE.getNum()).thenReturn(1); //does not work }

Esto es usar PowerMockMockito 1.4.10 y Mockito 1.8.5.


Si desea apagar lo que devuelve INSTANCE, puede hacerlo pero es un poco desagradable (utilizando la manipulación de código de bytes y de reflexión). Creé y probé un proyecto simple con tres clases usando PowerMock 1.4.12 / Mockito 1.9.0. Todas las clases estaban en el mismo paquete.

SingletonObject.java

public enum SingletonObject { INSTANCE; private int num; protected void setNum(int num) { this.num = num; } public int getNum() { return num; } }

SingletonConsumer.java

public class SingletonConsumer { public String consumeSingletonObject() { return String.valueOf(SingletonObject.INSTANCE.getNum()); } }

SingletonConsumerTest.java

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()); } }

La llamada al Whitebox.setInternalState reemplaza a INSTANCE con un objeto simulado que puede manipular dentro de su prueba.