Este es probablemente un PowerMock/EasyMock 101 pregunta que no puedo averiguar por qué.
Tengo un clase C con métodos

public static boolean testInner(String s) {
    return false;
}

public static boolean testOuter() {
    String x = "someValue";
    return testInner(x);
}

En mi prueba de testOuter() método que desea asegurarse de testInner se llama con el parámetro adecuado. Para hacerlo, yo estoy haciendo algo parecido a esto: [@RunWith(PowerMockRunner.class)
@PrepareForTest(EmailUtil.class declaró que a nivel de Clase]

EasyMock.expect(C.testInner("blabla")).andReturn(true);
PowerMock.replayAll();
boolean status = C.testOuter();
PowerMock.verifyAll();  
assertTrue(status);

Pero estoy recibiendo de error como:

java.lang.AssertionError: 
Unexpected method call testOuter():
testInner("blabla"): expected: 1, actual: 0
    at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:45)
    at org.powermock.api.easymock.internal.invocationcontrol.EasyMockMethodInvocationControl.invoke(EasyMockMethodInvocationControl.java:95)
    at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:105)
    at org.powermock.core.MockGateway.methodCall(MockGateway.java:60)
    at C.testOuter(C.java)

He sustituido el parámetro real con EasyMock.IsA(String.class) pero no ha habido suerte. Estoy bastante seguro de que estoy haciendo algo fundamentalmente tonto aquí.
Alguna ayuda?

InformationsquelleAutor phewataal | 2012-01-26

3 Comentarios

  1. 13

    Creo que hay dos cuestiones aquí, uno tiene que hacer con una llamada perdida en el código de prueba. La segunda tiene que ver con su comprensión del comportamiento de las burlas, y la diferencia entre el total y parcial de burla.

    Llamadas Perdidas

    Parece que te falta una llamada a PowerMock.mockStatic o uno de los PowerMock.mockPartialMock métodos (véase también este). El primer método se burlan de todos los métodos estáticos pasado, mientras que el segundo se burlan de la lista de métodos que se da.

    Un Ejemplo

    Aquí está un ejemplo completo con dos métodos de prueba que ilustran las dos opciones. En primer lugar, hemos de anotar la clase de prueba con estas dos anotaciones:

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(Dummy.class)
    public class DummyTest {

    La primera anotación dice JUnit para ejecutar la prueba con PowerMockRunner. La segunda anotación se dice PowerMock a preparar para burlarse de la clase Ficticio.

    Totalmente Estático Simulacro

    Siguiente, veremos un ejemplo donde todos los métodos estáticos de la clase Dummy son objeto de burla. ¿Qué significa esto? Esto significa esencialmente que te gustaría reemplazar la implementación real con los falsos (se ríe). ¿Cómo debe esta falsa aplicación comportarse? Esto es lo que se especifique en la espera.

    Así, en el testStaticMock método, estamos diciéndole a EasyMock para darnos una falsa aplicación de los dos métodos. Te gusta el falso Dummy.testOuter para devolver simplemente true. Y te gusta el muñeco falso.testInner para volver true cuando se pasa el argumento "bb". Tenga en cuenta que cuando estos se burla activados (PowerMock.replayAll), el código de prueba sólo se ejecutará el falso métodos y no de la implementación, este parece ser el origen de la confusión. Tengo más que decir sobre esto más adelante.

        @Test
        public void testStaticMock() {
            mockStatic(Dummy.class);
            EasyMock.expect(Dummy.testOuter()).andReturn(true);
            EasyMock.expect(Dummy.testInner("bb")).andReturn(true);
            replayAll();
            boolean status = Dummy.testOuter();
            Assert.assertTrue(status);
            status = Dummy.testInner("bb");
            Assert.assertTrue(status);
            verifyAll();
        }

    Parcial Estática Simulacro

    Aquí está otra prueba en la que no burlarse de todos los métodos, sólo los que pasamos a mockStaticPartial. A continuación, le estamos diciendo a PowerMock que sólo queremos simular el método Dummy.testInner. Por lo tanto, parte de Dummy es objeto de burla y el resto es la clase bajo prueba.

        @Test
        public void testPartialStaticMock() {
            mockStaticPartial(Dummy.class, "testInner");
            EasyMock.expect(Dummy.testInner("someValue")).andReturn(true);
            replayAll();
            boolean status = Dummy.testOuter();
            verifyAll();
            Assert.assertTrue(status);
        }
    }

    Y dejar que el se burlaban de clase Dummy se definen de la siguiente manera:

    public class Dummy {
        public static boolean testInner(String s) {
            return false;
        }
    
        public static boolean testOuter() {
            String x = "someValue";
            return testInner(x);
        }
    }

    Completa burla vs Parcial de Burla

    Una cosa a entender acerca de los estática burla es que todos los métodos estáticos son objeto de burla. Por lo tanto, el método testOuter le sustituya por una burla versión tendrá una implementación como la siguiente:

        public static boolean testOuter() {
            return true; //or whatever value is provided in the expectation
        }

    Por lo tanto, no debemos esperar que se burlaban de la versión para llamar a los métodos que la real en la aplicación. No queremos la atención acerca de los componentes internos del método. Este fue el motivo, hemos decidido burlarse de todos modos, para reemplazar su funcionamiento interno con un juguete de la aplicación, que se define sólo por la expectativa que hemos establecido para ella.

    Uno el otro lado, cuando hicimos parcial de burla, que no burlarse de testOuter, por lo que nos invocar su aplicación real.

    • Gracias por las explicaciones detalladas.Era mi incapacidad para distinguir parcial vs llena de burla que condujo a la cuestión.
  2. 1

    Sólo estás diciendo EasyMock a esperar una llamada a testInner(), no testOuter().

     Unexpected method call testOuter():

    Intentado esto:

    EasyMock.expect(C.testInner("blabla")).andReturn(true);
    EasyMock.expect(C.testOuter());
    PowerMock.replayAll();
    • Gracias Pedro. He añadido el testOuter() esperar, pero ahora estoy consiguiendo: java.lang.IllegalStateException: falta de definición de comportamiento para el método anterior llamada testOuter() at org.easymock.interna.MocksControl.replay(MocksControl.java:174)
    • Hmm, aparentemente demasiado tiempo desde que he utilizado EasyMock 🙂 tal vez fue como este….EasyMock.esperar(C. testOuter()).andReturn(true);
  3. 0

    De responder a proporcionar un ejemplo de flujo de llamadas a burlarse de una static void función utilizando mockStaticPartial().

    PowerMock.mockStaticPartial(Sample.class, "test");
    Sample.test();
    EasyMock.expectLastCall();
    PowerMock.replay(Sample.class);

    Más tarde, en la prueba de si se llama algo así como:

    assertFalse(Sample.returnFalseBool());

    La prueba se llame al método real ya que sólo la función test() ha sido objeto de burla en este caso.

    Descargo de responsabilidad: soy consciente de que esto podría no ser el MEJOR lugar para agregar esta respuesta, pero juntando un par de otras respuestas a diversas preguntas relacionadas con el me ayudó a venir para arriba con esta respuesta, sintió que era necesario para ponerlo en algún lugar.

Dejar respuesta

Please enter your comment!
Please enter your name here