4.1 Параметры методов

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

Так тоже можно делать. Если вы хотите, чтобы при определенном параметре метод возвращал что-то определенное, то правило можно записать так:

Mockito.doReturn(результат).when(объект).имяМетода(параметр);

И сразу рассмотрим пример, чтобы лучше все понять. Пусть наш List возвращает имя Иван при запросе 10-го элемента, и имя Марья при запросе 500-го. Сказано – сделано.


@ExtendWith(MockitoExtension.class)
class ParamsTest {
    @Mock
    List mockList;
 
    @Test
    public void whenMockAnnotation() {
        //добавление первого правила
        Mockito.doReturn("Иван").when(mockList).get(10);       
        //добавление второго правила
        Mockito.doReturn("Марья").when(mockList).get(500);  
 
        assertEquals("Иван", mockList.get(10)); 
        assertEquals("Марья", mockList.get(500)); 
 
    }
}

4.2 Шаблоны параметров

И сразу хитрые коллеги зададут мне вопрос: “А как быть, если метод требует аргументы, но при любых значениях должен возвращать один и тот же результат?”. Не будем же мы писать:


Mockito.doReturn("Иван").when(mockList).get(1);  
Mockito.doReturn("Иван").when(mockList).get(2); 
Mockito.doReturn("Иван").when(mockList).get(99);   

Нет, никто тебя так писать не заставляет. Если ты хочешь добавить правило mock-объекту, которое действует для метода с любыми аргументами, то для этого есть специальный объект:

Mockito.any()

Наш пример с его помощью будет записан так:

Mockito.doReturn("Иван").when(mockList).get(any(int.class));

Есть тут пара нюансов. Объект Mockito.any() имеет тип Object, поэтому для параметров разных типов есть его аналоги:

Метод Тип параметра
1 any() Object, включая null
2 any(ClassName.class) ClassName
3 anyInt() int
4 anyBoolean() boolean
5 anyDouble() double
6 anyList() List

Более корректно наш пример будет выглядеть так:

Mockito.doReturn("Иван").when(mockList).get(anyInt());

4.3 Метод doAnswer()

Мы добрались до сложного поведения виртуальных методов. Рано или поздно наступит ситуация, когда ты захочешь, чтобы этот виртуальный метод имел сложное поведение. Например, он должен возвращать значения в зависимости от параметров, преобразовывать строку в верхний регистр.

Для этого есть специальный метод – doAnswer(), в который передается функция, которая делает то, что тебе нужно:

Mockito.doAnswer(функция).when(объект).имяМетода(параметр);

Давай заставим метод get() класса List возвращать квадрат переданного ему аргумента. И напишем такую программу:


@ExtendWith(MockitoExtension.class)
class DoAnswerTest {
    @Mock
    List mockList;
 
    @Test
    public void whenMockAnnotation() {
        Mockito.doAnswer(invocation -> {
            int parameter = invocation.getArgument(0);
            return parameter * parameter;
        }).when(mockList).get(anyInt());   
 
        assertEquals(100, mockList.get(10)); 
        assertEquals(25, mockList.get(5)); 
    }
}

Функцию мы задали с помощью объект класса Answer.