¿Cómo simular un método privado para realizar pruebas usando PowerMock?
Tengo una clase que me gustaría probar con un método público que llama a uno privado. Me gustaría asumir que el método privado funciona correctamente. Por ejemplo, me gustaría algo como doReturn....when...
. Descubrí que existe una posible solución usando PowerMock , pero esta solución no me funciona. ¿Cómo se puede hacer? ¿Alguien tuvo este problema?
No veo ningún problema aquí. Con el siguiente código usando la API de Mockito, logré hacer precisamente eso:
public class CodeWithPrivateMethod {
public void meaningfulPublicApi() {
if (doTheGamble("Whatever", 1 << 3)) {
throw new RuntimeException("boom");
}
}
private boolean doTheGamble(String whatever, int binary) {
Random random = new Random(System.nanoTime());
boolean gamble = random.nextBoolean();
return gamble;
}
}
Y aquí está la prueba JUnit:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.api.support.membermodification.MemberMatcher.method;
@RunWith(PowerMockRunner.class)
@PrepareForTest(CodeWithPrivateMethod.class)
public class CodeWithPrivateMethodTest {
@Test(expected = RuntimeException.class)
public void when_gambling_is_true_then_always_explode() throws Exception {
CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod());
when(spy, method(CodeWithPrivateMethod.class, "doTheGamble", String.class, int.class))
.withArguments(anyString(), anyInt())
.thenReturn(true);
spy.meaningfulPublicApi();
}
}
Una solución genérica que funcionará con cualquier marco de prueba ( si su clase no es final
) es crear manualmente su propio simulacro.
- Cambie su método privado a protegido.
- En tu clase de prueba extiende la clase.
- anule el método previamente privado para devolver cualquier constante que desee
Esto no utiliza ningún marco, por lo que no es tan elegante, pero siempre funcionará: incluso sin PowerMock. Alternativamente, puede usar Mockito para realizar los pasos 2 y 3 por usted, si ya realizó el paso 1.
Para simular un método privado directamente, deberá usar PowerMock como se muestra en la otra respuesta .