Пробное тестирование — это метод тестирования, в котором виртуальный объект используется для создания метода тестирования для определенных объектов, которые нелегко создать или получить в процессе тестирования. Что такое объект, который нелегко построить? Например, HttpServletRequest необходимо создать и получить в среде контейнера сервлетов. А как насчет объектов, к которым нелегко получить доступ? Например, для JedisCluster вам необходимо подготовить среду, связанную с Redis, затем настроить ее и т. д.
Mock может разлагать другие классы или интерфейсы, связанные с модульными тестами. Он может помочь вам смоделировать эти зависимости и проверить поведение вызываемых зависимостей.
Когда нам нужно протестировать OrderService, в соответствии с нашей обычной практикой мы должны сначала подготовить среды redis и db, а затем создать UserService и CouponService для их внедрения. На этом этапе нам нужно построить полное дерево зависимостей и файл. процесс относительно громоздкий, в случае, если база данных не может быть подключена, зависимости не найдены, сервис зависает... Со временем это может ослабить наш энтузиазм по поводу одиночного тестирования проекта, поэтому необходимо найти элегантный способ. чтобы решить эту проблему в настоящее время.
Данг-Данг-Данг~ В это время появился Mockito (в Java существует множество Mock-фреймворков, но в этой статье рассказывается только об этом), он преобразует все эти громоздкие зависимости в Mock Object, как показано ниже, чтобы мы могли сосредоточиться на нашей работе. тестирование сокращает время, затрачиваемое на разрешение зависимостей.
Я не буду здесь вдаваться в подробности внедрения Mockito. Если вам интересно, вы можете самостоятельно просмотреть официальную документацию. Здесь мы в основном познакомим вас с некоторыми часто используемыми методами Mock.
зависимость maven
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
Для удобства тестирования кода импортируйте статически напрямую в тестовый класс import static org.mockito.Mockito.*;
@Test
public void testMockBase(){
//Создаем Макет ArrayList объекта
List mockList = mock(ArrayList.class);
//pass
Assert.assertTrue(mockList instanceof ArrayList);
//Когда наш методockList вызывает метод add("Zhang San"), он возвращает true
When(mockList.add("Чжан Сан")).thenReturn(true);
//Когда наш методockList вызывает метод size(), он возвращает 10
when(mockList.size()).thenReturn(10);
//pass
Assert.assertTrue(mockList.add("Чжан Сан"));
//pass
Assert.assertFalse(mockList.добавить("Ли Си"));
//pass
Assert.assertEquals(mockList.size(),10);
//null
System.out.println(mockList.get(0));
}
Статический метод Mock создаст объект Mock. Поскольку объект Mock фактически не будет выполнять код в методе, если возвращаемое значение не указано, будет возвращено значение по умолчанию (например, строка 19). В девятой и десятой строках мы указываем значение, которое должен вернуть методockList после выполнения определенного метода, поэтому с проверкой AssertTrue проблем не возникает, но в добавить("Ли Си") мы его не установили, поэтому ЛОЖЬ.
//Используем макет
List mockedList = mock(ArrayList.class);
mockedList.add("once");
mockedList.add("twice");
mockedList.add("twice");
mockedList.add("three times");
mockedList.add("three times");
mockedList.add("three times");
//Здесь по умолчанию определяется, что метод вызывает times(1), как показано ниже
verify(mockedList).add("once");
verify(mockedList, times(1)).add("once");
verify(mockedList, times(2)).add("twice");
verify(mockedList, times(3)).add("three times");
//Никогда не вызывался, раз(0)
verify(mockedList, never()).add("never happened");
//Хоть один раз, хоть несколько раз, максимум несколько раз
verify(mockedList, atLeastOnce()).add("three times");
verify(mockedList, atLeast(2)).add("three times");
verify(mockedList, atMost(5)).add("three times");
На самом деле, в приведенном выше коде именование относительно интуитивно понятно, поэтому я прокомментировал его прямо в коде.
//Метод может пройти при выполнении в течение 100 мс
verify(mock, timeout(100)).someMethod();
//То же, что и выше
verify(mock, timeout(100).times(1)).someMethod();
//Длительность двух вызовов метода не превышала 100 мс.
verify(mock, timeout(100).times(2)).someMethod();
verify(mock, timeout(100).atLeast(2)).someMethod();
Благодаря обнаружению тайм-аута мы можем проверить, есть ли какие-либо проблемы в логике нашего метода, которые могут привести к тайм-ауту.
linkedList.add("element");
// anyInt() Любое целое число, которое мы возвращаем element
when(linkedList.get(anyInt())).thenReturn("element");
System.out.print(linkedList.get(10));//Возвращаем элемент
@Test(expected = RuntimeException.class)
public void doThrow(){
List list = mock(List.class);
doThrow(new RuntimeException()).when(list).add(1);
list.add(1);
}
public class ArticleManagerTest {
@Mock private ArticleCalculator calculator;
@Mock private ArticleDatabase database;
@Mock private UserProvider userProvider;
Следует отметить, что если мы используем его через аннотации, мы должны добавить код для инициализации макета, иначе он будет нулевым, даже если аннотации отмечены.
MockitoAnnotations.initMocks(testClass);
Для более подробного использования Mockito вы можете напрямую обратиться к официальной документации, потому что там действительно много «странных трюков». Поддержка лямбда-выражений java8 также будет обновлена позже. Многие функции еще предстоит изучить~.