Méthode de comptage invocations dans les essais unitaires

Quelle est la meilleure façon de compter les invocations de la méthode dans un test unitaire? Est-ce que l'un des cadres d'essai permet cela?

35
demandé sur user855 2011-10-08 09:26:48

7 réponses

il semble que vous pourriez vouloir utiliser le .attendes (1) type de méthodes que les cadres simulés fournissent habituellement.

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, vous faites ce qui 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)

45
répondu case nelson 2014-06-19 23:23:40

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();
12
répondu Jakub Kubrynski 2016-08-13 13:29:30

Vous pouvez compter le nombre d'invocation de méthode en utilisant la réponse d'interface 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);
7
répondu oleh.kovaliuk 2013-12-27 15:23:31

selon les méthodes que vous voulez Compter, vous pouvez créer une configuration de test, avec un @Before conseils correspondant à votre classe / paquet / 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 configs ci-dessus ou XML si vous le trouvez plus facile.

vous pouvez créer différents pointcuts / aspect si vous en avez besoin.

3
répondu tolitius 2011-10-08 06:37:32

donne 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 voulez vérifier si la méthode getRole(String) est appelée pour une fois.

Vous ferais 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";
        }
    }
}
3
répondu OlivierTerrien 2018-01-25 09:01:50

Il semble que vous voudrez peut-être un test espion. Voir, par exemple, Mockito.espion().

2
répondu Michael Brewer-Davis 2011-10-08 06:22:05

Vous avez un peu d'options

1) ajouter du code spécial qui compte les invocations dans la fonction. Ça marchera, mais ce n'est pas une bonne solution.

2) Après avoir effectué 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 appelée. C'est un processus très manuel donc c'est pas vraiment conçu pour les tests unitaires.

Une meilleure solution serait de vérifier que la sortie est ce que vous attendez plutôt que de vérifier le fonctionnement interne.

1
répondu Mark Robinson 2011-10-08 05:41:34