Plusieurs instructions RunWith dans jUnit

J’écris un test unitaire et souhaite utiliser JUnitParamsRunner et MockitoJUnitRunner pour une classe de test.

Malheureusement, ce qui suit ne fonctionne pas:

 @RunWith(MockitoJUnitRunner.class) @RunWith(JUnitParamsRunner.class) public class DatabaseModelTest { // some tests } 

Est-il possible d’utiliser les deux, Mockito et JUnitParams dans une seule classe de test?

Vous ne pouvez pas faire cela car selon les spécifications, vous ne pouvez pas mettre deux fois la même annotation sur le même élément annoté.

Alors, quelle est la solution? La solution est de ne placer qu’un seul @RunWith() avec runner que vous ne pouvez pas @RunWith() et en remplacer un autre par quelque chose. Dans votre cas, je suppose que vous allez supprimer MockitoJUnitRunner et faire ce qu’il fait par programmation.

En fait, la seule chose qu’il fait fonctionne:

 MockitoAnnotations.initMocks(test); 

au début du test élémentaire. La solution la plus simple consiste donc à mettre ce code dans la méthode setUp() :

 @Before public void setUp() { MockitoAnnotations.initMocks(this); } 

Je ne suis pas sûr, mais vous devriez probablement éviter les appels multiples de cette méthode en utilisant le drapeau:

 private boolean mockInitialized = false; @Before public void setUp() { if (!mockInitialized) { MockitoAnnotations.initMocks(this); mockInitialized = true; } } 

Quoi qu’il en soit, une solution réutilisable peut être implémentée avec les règles de JUnt.

 public class MockitoRule extends TestWatcher { private boolean mockInitialized = false; @Override protected void starting(Description d) { if (!mockInitialized) { MockitoAnnotations.initMocks(this); mockInitialized = true; } } } 

Ajoutez maintenant la ligne suivante à votre cas de test:

 @Rule public MockitoRule mockitoRule = new MockitoRule(); 

et vous pouvez exécuter ce cas de test avec n’importe quel coureur que vous voulez.

A partir de JUnit 4.7 et Mockito 1.10.17, cette fonctionnalité est intégrée. il y a une classe org.mockito.junit.MockitoRule . Vous pouvez simplement l’importer et append la ligne

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

à votre classe de test.

Cette solution fonctionne pour tous les coureurs possibles, pas seulement cet exemple de mockito. Par exemple; pour le spring, changez simplement les classes de coureur et ajoutez les annotations nécessaires.

 @RunWith(JUnitParamsRunner.class) public class DatabaseModelTest { @Test public void subRunner() throws Exception { JUnitCore.runClasses(TestMockitoJUnitRunner.class); } @RunWith(MockitoJUnitRunner.class) public static class TestMockitoJUnitRunner { } } 

DatabaseModelTest sera exécuté par JUnit. TestMockitoJUnitRunner dépend (par la logique) et il sera exécuté à l’ intérieur de la méthode principale dans une méthode @Test , pendant l’appel JUnitCore.runClasses(TestMockitoJUnitRunner.class) . Cette méthode garantit que le runner principal est démarré correctement avant l’exécution du sous-programme d’exécution, implémentant efficacement plusieurs annotations @RunWith nestedes avec des classes de test dépendantes.

Aussi sur https://bekce.github.io/junit-multiple-runwith-dependent-tests

Dans mon cas, j’essayais de se moquer d’une méthode dans la fève de spring et

 MockitoAnnotations.initMocks(test); 

ne fonctionne pas. Au lieu de cela, vous devez définir ce bean pour qu’il soit construit à l’aide d’une méthode simulée dans votre fichier XML, comme suit.

 ...    ... 

et ajoutez ce bean avec autowired dans votre classe de test comme suit.

 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="file:springconfig.xml") public class TestClass { ... @Autowired private ClassWantedToBeMocked classWantedToBeMocked; ... when(classWantedToBeMocked.methodWantedToBeMocked()).thenReturn(...); ... } 

Depuis la sortie de PowerMock 1.6, vous pouvez le faire aussi facilement que

 @RunWith(PowerMockRunner.class) @PowerMockRunnerDelegate(JUnitParamsRunner.class) public class DatabaseModelTest { // some tests } 

Expliqué ici https://blog.jayway.com/2014/11/29/using-another-junit-runner-with-powermock/

Vous pouvez également essayer ceci:

 @RunWith(JUnitParamsRunner.class) public class AbstractTestClass { // some tests } @RunWith(MockitoJUnitRunner.class) public class DatabaseModelTest extends AbstractTestClass { // some tests }