2012-05-29 23 views
68

Al escribir una nueva prueba junit4, me pregunto si va a utilizar @RunWith (MockitoJUnitRunner.class) o MockitoAnnotations.initMocks (este).@RunWith (MockitoJUnitRunner.class) vs MockitoAnnotations.initMocks (este)

Creé una nueva prueba & el asistente generó automáticamente una prueba con el Runner. Javadocs para el estado de la MockitoJUnitRunner siguientes:

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

Inicializa burla anotado con Mock, por lo que el uso explícito de MockitoAnnotations.initMocks (objeto) 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 es claro si el uso del corredor tiene ninguna ventaja sobre los initMocks() método que han estado utilizando en el pasado.

¡Cualquier comentario o enlace sería apreciado!

Respuesta

85

MockitoJUnitRunner le da la validación automática del uso del marco, así como un initMocks() automático.

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

  • se llama al método estático when, pero no completa el tropezar con un juego thenReturn, thenThrow o then. (1 Error en el código de abajo)

  • Usted llama verify en un simulacro, pero se olvida de proporcionar el método llamado que usted está tratando de verificar. (Error 2 en el código de abajo)

  • se llama al método when después doReturn, doThrow o doAnswer y pasar una maqueta, pero se olvidan de proporcionar el método que que está intentando trozo. (3 error en el código de abajo)

Si usted no tiene la validación del uso de marco, estos errores no son reportados hasta la siguiente llamada a un método Mockito.Esto podría ser

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

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

Así es como 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 empecé a escribir esta respuesta hace más de cinco años, escribí

Por lo que recomiendo el uso de la MockitoJUnitRunner siempre que 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 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 el MockitoJUnitRunner. Pero es mejor, porque no excluye el uso de otros corredores.

Incluir

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

en su clase de prueba. Esto inicializa los simulacros y automatiza la validación del marco; al igual que MockitoJUnitRunner hace. Pero ahora, puede 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.

+3

Consulte los [javadocs de 'Mockito.validateMockitoUsage()'] (http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#validateMockitoUsage%28%29) para obtener más información sobre este validación. – avandeursen

+0

definitivamente no puedo decir que son lo mismo. en un caso de prueba, la configuración de junit runner falla para mí y no inyecta mis simulacros correctamente a menos que haga la configuración de initMocks – dtc

+0

Estamos usando testng 6.8.8 + mockito 1.10.19 y, obviamente, no podemos usar MockitoJUnitRunner, pero ¡el marco de validación aún funciona! Y funciona exactamente como @David Wallace. ¿Alguien puede explicar? ¿Esto es porque todavía tenemos @ Before * callbacks y MockitoAnnotations.initMocks (this)? – yuranos87

23

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

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

+1

Aparte de la línea initMocks(), el método @Before aún sería necesario para cualquier otra configuración, ¿verdad? – OceanBlue

+1

@OceanBlue: Por supuesto, si su método '@ Before' contenía algo excepto' initMocks() ', debe conservarlo después de migrar a runner. –

+0

La respuesta de David Wallace sobre la validación de framework responde completamente a mi pregunta, así que acepté esa, pero +1 para señalar que este corredor no se puede usar con otro, como el de Spring. ¡Gracias! – OceanBlue

Cuestiones relacionadas