Quelle est la meilleure façon de compter les appels de méthode dans un test unitaire. Est-ce que l'un des frameworks de test le permet ?
Réponses
Trop de publicités?Il semble que vous souhaitiez utiliser les .expects(1)
que les frameworks fictifs 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());
Source - 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();
Étant donné un exemple de classe "RoleRepository" avec une seule méthode "getRole(String user)" qui renverrait un rôle.
En supposant que vous ayez déclaré cet objet comme Mock ou Spy et que vous vouliez vérifier si la méthode getRole(String) est appelée une fois par 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";
}
}
}
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);
Selon les méthodes que vous souhaitez compter, vous pouvez créer une configuration de test, avec un @Before
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 de coupe / aspect si vous en avez besoin.