Estoy tratando de burlarse de un método privado que está haciendo una llamada JNDI. Cuando se llama a ese método desde una prueba unitaria, arroja una excepción ^. Me gustaría descartar ese método para fines de prueba. Usé el sample code from another questions answer, y mientras pasa la prueba, parece que el método subyacente aún se llama. Inserté un System.err.println()
en el método doTheGamble()
, y se imprime en mi consola.Se burló de método privado con PowerMock, pero el método subyacente todavía se llama
Bastante interesante, si hago el comentario de la primera assertThat
, la prueba pasa. ? :(
Así que, ¿cómo se burlan de un método privado por lo que no consigo llamado?
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
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;
import java.util.Random;
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;
@RunWith(PowerMockRunner.class)
@PrepareForTest(CodeWithPrivateMethod.class)
public class PowerMock_Test {
static boolean gambleCalled = false;
@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);
/* 1 */ assertThat(PowerMock_Test.gambleCalled, is(false));
spy.meaningfulPublicApi();
/* 2 */ assertThat(PowerMock_Test.gambleCalled, is(false));
}
}
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();
System.err.println("\n>>> GAMBLE CALLED <<<\n");
PowerMock_Test.gambleCalled = true;
return gamble;
}
}
^como es comprensible, ya que mi espacio de trabajo no es compatible con JNDI, sólo el entorno de producción hace
% estoy usando las últimas versiones de toda la biblioteca, JUnit 4.10, Mockito 1.8.5, 1.1 Hamcrest, Javassist 3.15.0, y PowerMock 1.4.10.
+1 para no dañar los errores. Muy cuidado de ti;) – Guillaume
@Mike ¿Tienes alguna idea de por qué 'doReturn (true) .when (spy," doTheGamble ", anyString(), anyInt());' funciona pero 'doReturn (true) .when (spy , método (CodeWithPrivateMethod.class, "doTheGamble", String.class, int.class)) .withArguments (anyString(), anyInt()); 'da como resultado 'IllegalArgumentException: argument type mismatch'? Este último parece más acorde con el estilo del ejemplo y al menos equivalente, pero no funciona. – ArtB
Honestamente, no puedo, lo siento. Soy relativamente nuevo en Mockito/PowerMock ... Nunca intenté escribir código en ese estilo ('.withArguments (...)') antes. – Mike