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

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

JSP & Servlets
4 уровень , 4 лекция
Открыта

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());  
    }
}
Комментарии (13)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Олег Уровень 106 Expert
30 августа 2024
Ощущение, что тут все всё понимают, но не я :с
Роман Уровень 88
13 октября 2024
да не, бро, просто такие как мы почти не пишем комментарии, так как и писать то нечего
Al'murat Zhilkamanov Уровень 12
16 марта 2024
Кайба был тут.
jvatechs Уровень 111 Expert
16 мая 2023
Так-так, а где приведение типов?

    @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
А зачем если в примере уже указан тип хранения ArrayList

@Mock
List<String> mockList;
Anonymous #885613 Уровень 40
4 апреля 2023
Так лучше работает:

    @Mock
    List<String> mockList = mock(List.class);
Stas S Уровень 108 Expert
8 сентября 2022

Во время вызова метода verify() мы задали правило, что у объекта mockitoList должен вызваться метод get() с параметром 10.
Мы НЕ задаем никаких правил. Простой вызов метода с параметром и проверка, что он был вызван с данным параметром. Вызов метода в assert-ах тоже считается, в отличии от вызова метода в служебных выражениях самого Mockito. (when - do и т.д.)
Konstantin Уровень 111 Expert
26 июня 2022
Есть подозрения, что метод

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 Shamshurin Уровень 1
2 августа 2022
Да, всё верно.
BlackGrizzli Team Уровень 46
12 марта 2023
Это логично, если вызвать verify до вызова get() тест как бы должен упасть.
OB11TO Уровень 14
20 июня 2022
Исправьте


String name = mockList).get( 1 );  //вызов метода
String name = mockList).get( 2 );  //вызов метода
String name = mockList).get( 3 );  //вызов метода
dimarik236 Уровень 41
18 июня 2022

String name = mockList).get(10);
скобочка кажется лишняя
Kostas Уровень 30 Expert
24 марта 2025
может, это не скобочка, а улыбочка? 😊