Коротка відповідь полягає в тому, що у вашому прикладі результатом mock.method()
буде порожнє значення, відповідне типу; mockito використовує опосередкування за допомогою проксі, методу перехоплення та спільного екземпляра MockingProgress
класу для того, щоб визначити, чи викликання методу в макеті є для заглушки або перетворення наявної заглушеної поведінки, а не передачі інформації про заглушку через повернене значення глузливий метод.
Міні-аналіз за пару хвилин, дивлячись на макетний код, виглядає наступним чином. Зауважте, це дуже приблизний опис - тут дуже багато деталей. Я пропоную вам перевірити джерело на Github самостійно.
По-перше, коли ви знущаєтесь над класом, використовуючи mock
метод Mockito
класу, це по суті відбувається:
Mockito.mock
делегує до org.mockito.internal.MockitoCore
.mock, передаючи параметри макету за замовчуванням як параметр.
MockitoCore.mock
делегати org.mockito.internal.util.MockUtil
.createMock
MockUtil
Клас використовує ClassPathLoader
клас , щоб отримати примірник MockMaker
використовувати для створення знущатися. За замовчуванням використовується клас CgLibMockMaker .
CgLibMockMaker
використовує клас, запозичений у JMock, ClassImposterizer
який обробляє створення макета. Ключові фрагменти "магічної макети", які MethodInterceptor
використовуються для створення макету: мокіто MethodInterceptorFilter
та ланцюжок екземплярів MockHandler, включаючи екземпляр MockHandlerImpl . Перехоплювач методів передає виклики екземпляру MockHandlerImpl, який реалізує логіку бізнесу, яку слід застосувати, коли метод викликається на макеті (тобто, пошук, щоб відповідь записано вже, визначення, чи виклик являє собою нову заглушку тощо). Станом за замовчуванням є те, що якщо заглушка ще не зареєстрована для методу, що викликається, повертається відповідне типу порожнє значення.
Тепер давайте розглянемо код у вашому прикладі:
when(mock.method()).thenReturn(someValue)
Ось порядок виконання цього коду в:
mock.method()
when(<result of step 1>)
<result of step 2>.thenReturn
Ключовим моментом для розуміння того, що відбувається, є те, що відбувається, коли викликається метод на макеті: перехоплювач методу передає інформацію про виклик методу та делегує його ланцюгу MockHandler
екземплярів, які в підсумку делегуються MockHandlerImpl#handle
. Під MockHandlerImpl#handle
час обробник макетів створює екземпляр OngoingStubbingImpl
і передає його спільному MockingProgress
екземпляру.
Коли when
метод викликається після виклику method()
, він делегується до MockitoCore.when
, який викликає stub()
метод того ж класу. Цей метод розпаковує поточну заглушку із спільного MockingProgress
екземпляра, в яку записано method()
глузливе виклик, і повертає його. Потім thenReturn
метод викликається в OngoingStubbing
екземплярі.