¿Cómo simular un método privado para realizar pruebas usando PowerMock?

Resuelto Julie Langstrump asked hace 13 años • 6 respuestas

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?

Julie Langstrump avatar Oct 18 '11 14:10 Julie Langstrump
Aceptado

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();
    }
}
bric3 avatar Oct 18 '2011 08:10 bric3

Una solución genérica que funcionará con cualquier marco de prueba ( si su clase no es final) es crear manualmente su propio simulacro.

  1. Cambie su método privado a protegido.
  2. En tu clase de prueba extiende la clase.
  3. 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 .

Sled avatar Oct 19 '2011 19:10 Sled