@RunWith (MockitoJUnitRunner.class) vs MockitoAnnotations.initMocks (questo)

Mentre sto scrivendo un nuovo test di jUnit4, mi chiedo se usare @RunWith (MockitoJUnitRunner.class) o MockitoAnnotations.initMocks (questo) .

Ho creato un nuovo test e il wizard ha generato automaticamente un test con il Runner. Javadocs per MockitoJUnitRunner dichiara quanto segue:

Compatibile con JUnit 4.4 e versioni successive, questo runner aggiunge il seguente comportamento:

Inizializza i mock annotati con Mock, in modo che l’uso esplicito di MockitoAnnotations.initMocks (Object) non sia necessario. I mazzi sono inizializzati prima di ogni metodo di prova. convalida l’utilizzo della struttura dopo ogni metodo di prova.

Non mi è chiaro se usare il Runner abbia qualche vantaggio rispetto al metodo initMocks () che ho usato in passato.

Qualsiasi pensiero o collegamento sarebbe apprezzato!

MockitoJUnitRunner fornisce la convalida automatica dell’utilizzo del framework, nonché un initMocks() automatico initMocks() .

La validazione automatica dell’utilizzo del framework è davvero degna di essere. Ti dà un resoconto migliore se fai uno di questi errori.

  • Si chiama statico when thenReturn metodo, ma non si completa lo stubing con un matching thenReturn , thenThrow o then . (Errore 1 nel codice qui sotto)

  • Chiama verify su un simulato, ma dimentica di fornire la chiamata al metodo che stai tentando di verificare. (Errore 2 nel codice qui sotto)

  • Si chiama il metodo doReturn dopo doReturn , doThrow o doAnswer e si passa una simulazione, ma si dimentica di fornire il metodo che si sta tentando di eseguire lo stub. (Errore 3 nel codice qui sotto)

Se non si dispone della convalida dell’utilizzo del framework, questi errori non vengono segnalati fino alla seguente chiamata a un metodo Mockito. Questo potrebbe essere

  • nello stesso metodo di test (come l’errore 1 di seguito),
  • nel prossimo metodo di test (come l’errore 2 di seguito),
  • nella prossima lezione di test.

Se si verificano nell’ultimo test eseguito (come l’errore 3 di seguito), non verranno segnalati affatto.

Ecco come potrebbero apparire ciascuno di questi tipi di errori. Supponiamo qui che JUnit esegua questi test nell’ordine in cui sono elencati qui.

 @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. } 

Ora, quando ho scritto questa risposta per la prima volta più di cinque anni fa, ho scritto

Quindi consiglierei l’uso del MockitoJUnitRunner ovunque sia ansible. Tuttavia, come ha giustamente sottolineato Tomasz Nurkiewicz, non è ansible utilizzarlo se hai bisogno di un altro corridore JUnit, come quello di Primavera.

La mia raccomandazione ora è cambiata. Il team di Mockito ha aggiunto una nuova funzione da quando ho scritto questa risposta per la prima volta. È una regola JUnit, che svolge esattamente la stessa funzione di MockitoJUnitRunner . Ma è meglio, perché non preclude l’uso di altri corridori.

Includere

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

nella tua class di test. Questo inizializza i mock e automatizza la convalida del framework; proprio come fa MockitoJUnitRunner . Ma ora puoi usare SpringJUnit4ClassRunner o qualsiasi altro JUnitRunner. Da Mockito 2.1.0 in poi, ci sono opzioni aggiuntive che controllano esattamente quale tipo di problemi vengono segnalati.

L’uso del runner ti consente di salvare un po ‘di codice (non è necessario il metodo @Before ). D’altra parte l’uso di un corridore a volte non è ansible, cioè quando ne stai già utilizzando uno, come SpringJUnit4ClassRunner .

Questo è tutto. È solo una questione di preferenza.