Как лучше всего подсчитать вызовы методов в модульном тесте. Любая из сред тестирования позволяет это?
Подсчет вызовов методов в модульных тестах
Ответы (7)
Похоже, вы, возможно, захотите использовать методы типа .expects(1)
, которые обычно предоставляют фиктивные фреймворки.
Используя mockito, если вы тестировали список и хотели убедиться, что clear был вызван 3 раза, а add был вызван хотя бы один раз с этими параметрами, вы делаете следующее:
List mock = mock(List.class);
someCodeThatInteractsWithMock();
verify(mock, times(3)).clear();
verify(mock, atLeastOnce()).add(anyObject());
Источник – MockitoVsEasyMock.
В Mockito вы можете сделать что-то вроде этого:
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();
Method
для equal
. Вспомните JS API Синон: stub.callCount
- person oligofren; 27.06.2018
Дан пример класса «RoleRepository» с одним методом «getRole (пользователь строки)», который возвращает роль.
Предположим, вы объявили этот объект как Mock или Spy и хотите проверить, вызывается ли метод getRole(String) один раз.
Вы бы сделали что-то вроде: 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";
}
}
}
Вы можете подсчитать количество вызовов метода, используя интерфейс Answer в 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);
В зависимости от того, какие методы вы хотите посчитать, вы можете создать тестовую конфигурацию с советом @Before
, соответствующим вашему классу/пакету/методу:
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
}
Вы можете использовать vanilla AspectJ или Spring AOP через вышеуказанные или XML-конфигурации, если вам это проще.
Вы можете создавать различные точки / аспекты, если вам нужно.
Похоже, вам может понадобиться тестовый шпион. См., например, Mockito.spy().
У вас есть несколько вариантов
1) Добавьте специальный код, который считает вызовы в функции. Это будет работать, но это не лучшее решение.
2) После запуска модульных тестов проверьте покрытие кода. Большинство инструментов покрытия учитывают вызовы, но на самом деле они предназначены для постобработки.
3) Используйте профайлер. Профилировщик позволит вам подсчитать, сколько раз вызывается функция. Это очень ручной процесс, поэтому он не предназначен для модульного тестирования.
Лучшим решением было бы проверить, что вывод соответствует вашим ожиданиям, а не проверять, как он работает внутри.