Pregunta @RunWith (MockitoJUnitRunner.class) vs MockitoAnnotations.initMocks (esto)


Mientras escribo una nueva prueba jUnit4, me pregunto si debo usar @RunWith (MockitoJUnitRunner.class)  o MockitoAnnotations.initMocks (esto).

Creé una nueva prueba y el asistente generó automáticamente una prueba con el Runner. Javadocs para MockitoJUnitRunner dice lo siguiente:

Compatible con JUnit 4.4 y superior, este corredor agrega el siguiente comportamiento:

Inicializa los simulacros anotados con Mock, por lo que el uso explícito de MockitoAnnotations.initMocks (Object) no es necesario. Los simulacros se inicializan antes de cada método de prueba.   valida el uso del marco después de cada método de prueba.

No tengo claro si usar el Runner tiene alguna ventaja sobre el initMocks () método que he estado usando en el pasado.

¡Cualquier pensamiento o enlace sería apreciado!


76
2018-05-29 20:34


origen


Respuestas:


MockitoJUnitRunner le da validación automática del uso del marco de trabajo, así como una automática initMocks().

La validación automática del uso del framework realmente vale la pena tener. Te proporciona mejores informes si cometes uno de estos errores.

  • Llamas a la estática when método, pero no complete el troceo con un thenReturn, thenThrow o then. (Error 1 en el código a continuación)

  • Llama verify en un simulacro, pero olvida proporcionar la llamada al método que estás tratando de verificar (Error 2 en el código a continuación)

  • Usted llama al when método después doReturn, doThrow o doAnswer y pasa un simulacro, pero olvida proporcionar el método que estás tratando de tropezar. (Error 3 en el código a continuación)

Si no tiene validación del uso del marco, estos errores no se informan hasta que siguiendo llamar a un método Mockito. Esto podría ser

  • en el mismo método de prueba (como el error 1 a continuación),
  • en el siguiente método de prueba (como el error 2 a continuación),
  • en la próxima clase de prueba.

Si ocurren en la última prueba que ejecuta (como el error 3 a continuación), no se informarán en absoluto.

A continuación se detalla cómo se vería cada uno de esos tipos de errores. Supongamos aquí que JUnit ejecuta estas pruebas en el orden en que se enumeran aquí.

@Test
public void test1() {

    // ERROR 1
    // This compiles and runs, but it's an invalid use of the framework because 
    // Mockito is still waiting to find out what it should do when myMethod is called.
    // But Mockito can't report it yet, because the call to thenReturn might 
    // be yet to happen.
    when(myMock.method1());

    doSomeTestingStuff();

    // ERROR 1 is reported on the following line, even though it's not the line with
    // the error.
    verify(myMock).method2();

}

@Test
public void test2() {

    doSomeTestingStuff();

    // ERROR 2
    // This compiles and runs, but it's an invalid use of the framework because
    // Mockito doesn't know what method call to verify.  But Mockito can't report 
    // it yet, because the call to the method that's being verified might 
    // be yet to happen.
    verify(myMock);
}

@Test
public void test3() {

    // ERROR 2 is reported on the following line, even though it's not even in 
    // the same test as the error.
    doReturn("Hello").when(myMock).method1();


    // ERROR 3
    // This compiles and runs, but it's an invalid use of the framework because
    // Mockito doesn't know what method call is being stubbed.  But Mockito can't 
    // report it yet, because the call to the method that's being stubbed might 
    // be yet to happen.

    doReturn("World").when(myMock);

    doSomeTestingStuff(); 

    //  ERROR 3 is never reported, because there are no more Mockito calls. 
}

Ahora cuando escribí esta respuesta por primera vez hace más de cinco años, escribí

Así que recomendaría el uso del MockitoJUnitRunner donde sea posible. Sin embargo, como Tomasz Nurkiewicz ha señalado correctamente, no puede usarlo si necesita otro corredor JUnit, como el de Spring.

Mi recomendación ahora ha cambiado. El equipo de Mockito ha agregado una nueva función desde que escribí esta respuesta por primera vez. Es una regla JUnit, que realiza exactamente la misma función que MockitoJUnitRunner. Pero es mejor, porque no excluye el uso de otros corredores.

Incluir

@Rule 
public MockitoRule rule = MockitoJUnit.rule();

en tu clase de prueba. Esto inicializa los simulacros y automatiza la validación del marco; al igual que MockitoJUnitRunner hace. Pero ahora, puedes usar SpringJUnit4ClassRunner o cualquier otro JUnitRunner también. Desde Mockito 2.1.0 en adelante, hay opciones adicionales que controlan exactamente qué tipo de problemas se informan.


95
2018-05-30 08:36



El uso de Runner le permite guardar un poco de codificación (sin necesidad de @Before método). Por otro lado, usar un corredor a veces no es posible, es decir, cuando ya está usando uno, como SpringJUnit4ClassRunner.

Eso es. Es solo una cuestión de preferencia.


23
2018-05-29 20:40