Quelle est la meilleure façon de compter les appels de méthode dans un test unitaire. L'un des cadres de test le permet-il?
Il semble que vous souhaitiez peut-être utiliser les méthodes de type .expects (1) que les frameworks factices fournissent généralement.
En utilisant mockito, si vous testiez une liste et que vous vouliez vérifier que clear a été appelé 3 fois et add a été appelé au moins une fois avec ces paramètres, procédez comme suit:
List mock = mock(List.class);
someCodeThatInteractsWithMock();
verify(mock, times(3)).clear();
verify(mock, atLeastOnce()).add(anyObject());
(De http://code.google.com/p/mockito/wiki/MockitoVSEasyMock )
Dans Mockito, vous pouvez faire quelque chose comme ceci:
YourService serviceMock = Mockito.mock(YourService.class);
// code using YourService
// details of all invocations including methods and arguments
Collection<Invocation> invocations = Mockito.mockingDetails(serviceMock).getInvocations();
// just a number of calls of any mock's methods
int numberOfCalls = invocations.size();
Vous pouvez compter le nombre d'appels de méthode en utilisant l'interface Answer dans Mockito.
ConnectionPool mockedConnectionPool = mock(ConnectionPool.class);
final int[] counter = new int[1];
when(mockedConnectionPool.getConnection()).then(new Answer<Connection>() {
@Override
public Connection answer(InvocationOnMock invocation) throws Throwable {
counter[0]++;
return conn;
}
});
// some your code
assertTrue(counter[0] == 1);
Étant donné un exemple de classe "RoleRepository" avec une seule méthode "getRole (String user)" qui retournerait un rôle.
En supposant que vous avez déclaré cet objet comme Mock ou Spy et que vous souhaitez vérifier si la méthode getRole (String) est appelée une fois à la fois.
Vous feriez quelque chose comme: Mockito.verify(roleRepository, Mockito.times(1)).getRole(Mockito.anyString());
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class RoleRepositoryTest {
@Spy
private RoleRepository roleRepository = new RoleRepository();
@Test
public void test() {
roleRepository.getRole("toto");
Mockito.verify(roleRepository, Mockito.times(1)).getRole(Mockito.anyString());
}
public static class RoleRepository {
public String getRole(String user) {
return "MyRole";
}
}
}
Selon les méthodes que vous souhaitez compter, vous pouvez créer une configuration de test, avec un @Before
conseils correspondant à votre classe/package/méthode:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class MethodCounterAspect {
private int counter = 0 // or inject the Counter object into this aspect
@Pointcut( "execution( * com.sample.your.package.*.*(..) )" )
public void methodsToCount() {}
@Before("methodsToCount()")
public void execute() throws Throwable {
counter++; // or update the counter injected into this aspect..
}
// get the counter
}
Vous pouvez utiliser Vanilla AspectJ ou Spring AOP via les configurations ci-dessus ou XML si vous le trouvez plus facile.
Vous pouvez créer différents points/aspects si vous en avez besoin.
Il semble que vous souhaitiez peut-être un test spy . Voir, par exemple, Mockito.spy () .
Vous avez quelques options
1) Ajoutez un code spécial qui compte les invocations dans la fonction. Cela fonctionnera, mais ce n'est pas une excellente solution.
2) Après avoir exécuté vos tests unitaires, vérifiez la couverture du code. La plupart des outils de couverture compteront les invocations mais ils sont vraiment conçus pour le post-traitement.
3) Utilisez un profileur. Un profileur vous permettra de compter combien de fois une fonction est invoquée. Il s'agit d'un processus très manuel, il n'est donc pas vraiment conçu pour les tests unitaires.
Une meilleure solution serait de vérifier que la sortie correspond à ce que vous attendez plutôt que de vérifier comment elle fonctionne en interne.