1. Метод doReturn()
А тепер буде магія.
Припустимо, ти створив фейковий мок-об'єкт, але ж треба, щоб він якось працював. Під час виклику певних методів робилося щось важливе, або методи повертали певний результат. Що робити?
Бібліотека Mockito дозволяє додати мок-об'єкту потрібну поведінку.
Якщо ти хочеш, щоб під час виклику певного методу мок-об'єкт повернув певний результат, це правило можна додати до об'єкту за допомогою коду:
Mockito.doReturn(результат).when(об'єкт).ім'яМетоду();
Бачиш наприкінці виклику методу ім'яМетоду?
Насправді жодного виклику тут немає. Метод doReturn()
повертає спеціальний proxy-об'єкт, за допомогою якого слідкує за викликами методів об'єкта, і таким чином йде запис правила.
Ще раз. Це просто такий хитрий спосіб записати правило, яке потрібно додати до мок-об'єкту. Потрібна певна вправність, щоб правильно інтерпретувати такий код у своїй голові, коли його бачиш. Із досвідом це прийде до тебе.
Думаю, потрібен конкретний приклад. Давай створимо мок-об'єкт класу ArrayList
і попросимо його метод size()
повернути число 10. Повний варіант коду виглядатиме так:
@ExtendWith(MockitoExtension.class)
class DoReturnTest {
@Mock
List mockList;
@Test
public void whenMockAnnotation () {
//створюємо правило: повернути 10 під час виклику метода size
Mockito.doReturn(10).when(mockList).size();
//тут викликається метод і поверне 10!
assertEquals(10, mockList.size());
}
}
Так, цей код працюватиме, тест не впаде.
2. Метод when()
Є ще один спосіб додати правило поведінки до мок-об'єкта – через виклик методу Mockito.when()
. Виглядає він так:
Mockito.when(об'єкт.ім'яМетоду()).thenReturn(результат);
Це такий самий спосіб запису правила поведінки мок-об'єкта, як і попередній. Порівняйте:
Mockito.doReturn(результат).when(об'єкт).ім'яМетоду();
Тут відбувається абсолютно те саме – конструювання нового правила.
Щоправда, перший приклад має два мінуси:
- виклик
об'єкт.ім'яМетоду()
сильно збиває з пантелику. - не працюватиме, якщо метод
ім'яМетоду()
повертаєvoid
.
Ну і давайте запишемо наш улюблений приклад за допомогою Mockito.when()
@ExtendWith(MockitoExtension.class)
class WhenTest {
@Mock
List mockList;
@Test
public void whenMockAnnotation() {
//створюємо правило: повернути 10 при виклику методу size
Mockito.when(mockList.size() ).thenReturn(10);
//тут викликається метод и поверне 10!
assertEquals(10, mockList.size());
}
}
3. Метод doThrow()
Ми розібралися, як зробити, щоб метод мок-об'єкта повернув певний результат. А як зробити так, щоб він кинув певний виняток? Передати його в doReturn()
?
Щоб метод не повернув, а саме викинув (throw) виняток, потрібно встановити правило за допомогою методу doThrow()
.
Mockito.doThrow(виняток.).when(об'єкт).ім'яМетоду();
І одразу другий варіант:
Mockito.when(об'єкт.ім'яМетоду()).thenThrow(виняток.);
Трохи очікувано, чи не так?
Ось бачиш, ти вже починаєш розумітися в цьому. Закріпимо знання прикладом:
@ExtendWith(MockitoExtension.class)
class DoThrowTest {
@Mock
List mockList;
@Test
public void whenMockAnnotation() {
Mockito.when(mockList.size() ).thenThrow(IllegalStateException.class);
mockList.size(); //тут кинеться виняток
}
}
Якщо потрібно викинути певний об'єкт-виняток, скористайся конструкцією виду:
Mockito.doThrow(new Виняток()).when(об'єкт).ім'яМетоду();
Просто передай до методу doThrow()
об'єкт виключення, і його буде викинуто під час виклику методу.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ