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));
}
}
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());
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.