Коротка відповідь полягає в тому, що у вашому прикладі результатом 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екземплярі.