J'écris un test unitaire et veux 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
}
Existe-t-il un moyen d'utiliser les deux, Mockito et JUnitParams dans une 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é.
Donc, quelle est la solution? La solution consiste à ne mettre qu'un @RunWith()
avec un coureur sans lequel vous ne pouvez pas vous en tenir et remplacer l'autre par un autre. Dans votre cas, je suppose que vous retirerez MockitoJUnitRunner
et ferez ce qu’il fait par programme.
En fait, la seule chose qu'il fait est de courir:
MockitoAnnotations.initMocks(test);
au début du cas de test. Donc, la solution la plus simple est de mettre ce code dans la méthode setUp()
:
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
Je ne suis pas sûr, mais probablement vous devriez éviter plusieurs appels de cette méthode en utilisant flag:
private boolean mockInitialized = false;
@Before
public void setUp() {
if (!mockInitialized) {
MockitoAnnotations.initMocks(this);
mockInitialized = true;
}
}
Cependant, 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 classe de test:
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
et vous pouvez exécuter ce cas de test avec le coureur de votre choix.
A partir de JUnit 4.7 et de Mockito 1.10.17, cette fonctionnalité est intégrée; il y a un org.mockito.junit.MockitoRule
classe. Vous pouvez simplement l'importer et ajouter la ligne
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
à votre classe de test.
Cette solution fonctionne pour tous les coureurs possibles, pas seulement cet exemple mockito. Par exemple; pour Spring, il suffit de changer les classes de coureurs et d'ajouter 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
en dépend (par logique) et il sera exécuté à l'intérieur du principal dans une méthode @Test
, pendant l'appel JUnitCore.runClasses(TestMockitoJUnitRunner.class)
. Cette méthode garantit que le coureur principal est démarré correctement avant que le sous-coureur static class TestMockitoJUnitRunner
Ne s'exécute, en implémentant efficacement plusieurs annotations @RunWith
Imbriquées avec des classes de test dépendantes.
Aussi sur https://bekce.github.io/junit-multiple-runwith-dependent-tests
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/
Dans mon cas, j’essayais de me moquer d’une méthode en fève de printemps et
MockitoAnnotations.initMocks(test);
ne fonctionne pas. Au lieu de cela, vous devez définir ce bean comme construit à l'aide de la méthode mock dans votre fichier XML, comme suit.
...
<bean id="classWantedToBeMocked" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="com.fullpath.ClassWantedToBeMocked" />
</bean>
...
et ajoutez ce haricot avec auto-câblé 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(...);
...
}
consultez ce lien https://bekce.github.io/junit-multiple-runwith-dependent-tests/ en utilisant cette approche, j'ai combiné un @RunWith (Parameterized.class) - coureur externe - avec @ RunWith (MockitoJUnitRunner.class) - Coureur interne. Le seul Tweak que je devais ajouter était de rendre mes variables membres dans la classe externe/coureur statique afin de les rendre accessibles au coureur/à la classe interne/imbriquée. bonne chance et profiter.