JavaRush/Курсы/JSP & Servlets/Выявление определенного поведения у объектов

Выявление определенного поведения у объектов

Открыта

5.1 Метод verify()

Кроме создания виртуальных объектов, часто возникает еще одна интересная задача – убедиться, что тестируемый класс вызвал нужные методы нужных объектов. Более того, вызвал нужное число раз, с правильными параметрами и тому подобное.

Для этого в Mockito тоже есть немного магии – семейство методов Mockito.verify(…). Общее правило, которым задается проверка вызова метода, имеет вид:

Mockito.verify(объект).имяМетода(параметр);

Пример:

@ExtendWith(MockitoExtension.class)
class VerifyTest {
 @Mock
 List<String> mockList;

 @Test
    public void whenMockAnnotation() {
        //вызов метода
        String name = mockList.get(10);

        //проверяем вызывался ли метод
        Mockito.verify(mockList).get(10);
    }
}

Во время вызова метода verify() мы задали правило, что у объекта mockitoList должен вызваться метод get() с параметром 10.

5.2 Метод verify() с проверкой количества вызовов

Иногда бывают более сложные сценарии проверки. Например, тебе нужно проверить не просто факт, что метод вызывался, а например, что он вызывался 3 раза. Или он у тебя вызывался в цикле и значит должен был вызваться N раз.

Мы не будем спрашивать, можно ли это сделать, мы сразу спросим: как записать такое правило? И опять Mockito нас не подводит. Правило можно задать в виде:

Mockito.verify(объект,количество).имяМетода(параметр);

Важно! Количество – это не тип int, а специальный объект, которые может задавать различные шаблоны. Помнишь разные варианты метода any() ? Тут тоже самое – есть специальные методы, с помощью которых можно задавать различные сценарии:

Метод Описание
1 never() Метод никогда не должен вызываться
2 times(n) n раз
3 atLeast(n) n или больше раз
4 atLeastOnce() 1 или больше раз
5 atMost(n) n или меньше раз
6 only() Должен быть только один вызов и только к этому методу

Пример:

String name1 = mockList.get(1);  //вызов метода
String name2 = mockList.get(2);  //вызов метода
String name3 = mockList.get(3);  //вызов метода

//проверяем, что метод get() вызывался 3 раза
Mockito.verify(mockList, times(3)).get(anyInt());

Ты также можешь потребовать, чтобы кроме указанных вызовов метода, никаких других обращений к объекту не было. Для этого есть правило:

Mockito.verifyNoMoreInteractions(объект);

5.3 Порядок вызова методов

Предыдущие правила никак не регламентировали порядок вызова методов. Правило просто должно выполниться и все. Но бывают ситуации, когда порядок вызовов методов важен и для этого у Mockito тоже есть решение.

Жесткий порядок вызова методов можно задать с помощью специального объекта InOrder. Сначала его нужно создать:

InOrder inOrder = Mockito.inOrder(объект);

А затем уже ему добавлять правила посредством вызова методов verify().

Пример:

List<String> mockedList = mock(MyList.class);
mockedList.size();
mockedList.add("a parameter");
mockedList.clear();

InOrder inOrder = Mockito.inOrder(mockedList);
inOrder.verify(mockedList).size();
inOrder.verify(mockedList).add("a parameter");
inOrder.verify(mockedList).clear();

5.4 Проверка исключений в Mockito

Факт того, что исключения возникли, проверяется немного по другому. Для этого нужно использовать метод assertThrows(). Общий формат такой проверки имеет вид:

Assertions.assertThrows(исключение.class, () -> объект.имяМетода());

Ничего сложного.

Пример:

@ExtendWith(MockitoExtension.class)
class ThenThrowTest {
 @Mock
 List mockList;

 @Test
    public void whenMockAnnotation() {
        //задаем поведение метода (нужно только для демонстрации)
        Mockito.when(mockList.size()).thenThrow(IllegalStateException.class);

        //проверяем бросится ли IllegalStateException при вызове метода size
        assertThrows(IllegalStateException.class, () -> mockList.size());
    }
}
Комментарии (15)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Олег
Уровень 106
Expert
30 августа 2024, 21:45
Ощущение, что тут все всё понимают, но не я :с
Роман
Уровень 88
13 октября 2024, 07:21
да не, бро, просто такие как мы почти не пишем комментарии, так как и писать то нечего
ShadyLine
Уровень 51
1 апреля, 10:13
Ну что? разобрался?
Дима
Уровень 70
18 августа, 13:28
Ну как дела спустя почти два года?
Al'murat Zhilkamanov
Уровень 12
16 марта 2024, 11:18
Кайба был тут.
jvatechsBackend Developer в Ищу стажировкуExpert
16 мая 2023, 22:53
Так-так, а где приведение типов?
@Test
public void whenMockAnnotation() {
    //вызов метода
    String name = mockList.get(10);

    //проверяем вызывался ли метод
    Mockito.verify(mockList).get(10);
}
где:
String name = mockList.get(10);
поменять на:
String name = (String) mockList.get(10);
Anonymous #3322801
Уровень 1
Expert
28 июля 2023, 18:18
А зачем если в примере уже указан тип хранения ArrayList
@Mock
List<String> mockList;
Anonymous #885613
Уровень 2
4 апреля 2023, 18:58
Так лучше работает:
@Mock
List<String> mockList = mock(List.class);
Stas S
Уровень 108
Expert
8 сентября 2022, 08:52
Во время вызова метода verify() мы задали правило, что у объекта mockitoList должен вызваться метод get() с параметром 10.
Мы НЕ задаем никаких правил. Простой вызов метода с параметром и проверка, что он был вызван с данным параметром. Вызов метода в assert-ах тоже считается, в отличии от вызова метода в служебных выражениях самого Mockito. (when - do и т.д.)
Konstantin Backend Developer Expert
26 июня 2022, 15:09
Есть подозрения, что метод
Mockito.verify(объект).имяМетода(параметр);
надо вызывать после выполнения проверяемых вызовов. Код из примеров лекции (и не только) у меня корректно отрабатывает только при вышеописанном условии! Например, первый тест падает, второй норм
@ExtendWith(MockitoExtension.class)
class TestClass {
    @Mock
    List mockList;

    @Test
    public void whenMockAnnotation1() {
        Mockito.doReturn("Иван").when(mockList).get(10);
        Mockito.verify(mockList).get(10); // проверка до вызова метода
        String name = (String) mockList.get(10);
    }

    @Test
    public void whenMockAnnotation2() {
        Mockito.doReturn("Иван").when(mockList).get(10);
        String name = (String) mockList.get(10);
        Mockito.verify(mockList).get(10); // проверка после вызова метода
    }
}
Vladislav ShamshurinJava Developer в Райффайзенбанк
2 августа 2022, 11:24
Да, всё верно.
BlackGrizzli Team
Уровень 46
12 марта 2023, 13:23
Это логично, если вызвать verify до вызова get() тест как бы должен упасть.
OB11TOBackend Developer в Мечтах
20 июня 2022, 14:49
Исправьте
String name = mockList).get( 1 );  //вызов метода
String name = mockList).get( 2 );  //вызов метода
String name = mockList).get( 3 );  //вызов метода
dimarik236System Engineer в Tinkoff.ru
18 июня 2022, 06:15
String name = mockList).get(10);
скобочка кажется лишняя
Kostas
Уровень 30
Expert
24 марта 2025, 19:48
может, это не скобочка, а улыбочка? 😊