@RunWith (MockitoJUnitRunner.classe) vs MockitoAnnotations.initMocks (this)

en écrivant un nouveau test jUnit4, je me demande s'il faut utiliser @RunWith(MockitoJUnitRunner.classe) ou MockitoAnnotations.initMocks (this) .

j'ai créé un nouveau test et l'assistant générée automatiquement un test avec le Coureur. Javadoc MockitoJUnitRunner de la manière suivante:

Compatible avec JUnit 4.4 et supérieur, ce coureur ajoute le comportement suivant:

initialise les moqueries annotées avec Mock, de sorte que l'usage explicite des MockitoAnnotations.initMocks (Object) n'est pas nécessaire. Les Mocks sont initialisés avant chaque méthode d'essai. valide l'utilisation du framework après chaque méthode d'essai.

Je ne sais pas si l'utilisation du coureur a un avantage sur la méthode initMocks () que j'ai utilisée dans le passé.

toute pensée ou lien serait apprécié!

81
demandé sur Hakan Serce 2012-05-30 00:34:46

2 réponses

MockitoJUnitRunner vous donne une validation automatique de l'utilisation du framework, ainsi qu'un initMocks() automatique .

la validation automatique de l'utilisation du framework vaut vraiment la peine. Il vous donne une meilleure information si vous faites une de ces erreurs.

  • vous appelez la méthode statique when , mais ne complétez pas le chaulage avec une correspondance thenReturn , thenThrow ou then . (Erreur 1 dans le code ci-dessous)

  • que Vous appelez verify sur une maquette, mais oublie de fournir à l'appel de la méthode que vous voulez vérifier. (erreur 2 dans le code ci-dessous)

  • vous appelez la méthode when après doReturn , doThrow ou doAnswer et passer un mock, mais oublier de fournir la méthode que vous essayez de stub. (Erreur 3 dans le code ci-dessous)

si vous n'avez pas de validation de l'utilisation du framework, ces erreurs ne sont pas rapportées avant l'appel suivant à une méthode Mockito. C'est peut-être

  • dans la même méthode d'essai (comme l'erreur 1 ci-dessous),
  • dans la méthode d'essai suivante (comme l'erreur 2 ci-dessous),
  • dans la classe d'essai suivante.

S'ils se produisent dans le dernier test que vous exécutez (comme l'erreur 3 ci-dessous), ils ne seront pas signalés du tout.

voici à quoi ressemble chacun de ces types d'erreurs. Supposons que JUnit fasse ces tests dans l'ordre où ils sont listés ici.

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

quand j'ai écrit cette réponse pour la première fois il y a plus de cinq ans, j'ai écrit

donc je recommande l'utilisation de la MockitoJUnitRunner dans la mesure du possible. Cependant, comme Tomasz Nurkiewicz l'a correctement souligné, vous ne pouvez pas l'utiliser si vous avez besoin d'un autre coureur JUnit, comme celui de printemps.

Ma recommandation a maintenant changé. L'équipe Mockito a ajouté une nouvelle fonctionnalité depuis que j'ai écrit cette réponse. C'est une règle de JUnit, qui remplit exactement la même fonction que le MockitoJUnitRunner . Mais c'est mieux, parce que ça n'empêche pas l'utilisation d'autres coureurs.

Inclure

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

dans votre classe de test. Cela initialise les mocks, et automatise la validation du framework, comme le fait MockitoJUnitRunner . Mais maintenant, vous pouvez utiliser SpringJUnit4ClassRunner ou tout autre JUnitRunner. À partir de Mockito 2.1.0, il y a des options supplémentaires qui contrôlent exactement le type de problèmes signalés.

103
répondu Dawood ibn Kareem 2017-06-28 10:28:22

en utilisant runner vous permet d'économiser un peu de codage (pas besoin de la méthode @Before ). D'un autre côté, l'utilisation d'un coureur est parfois impossible, c'est-à-dire lorsque vous en utilisez déjà un, comme SpringJUnit4ClassRunner .

C'est ça. C'est juste une question de préférence.

23
répondu Tomasz Nurkiewicz 2012-05-29 20:40:51