Короткий ответ заключается в том, что в вашем примере результатом mock.method()будет соответствующее типу пустое значение; mockito использует косвенное обращение через прокси, перехват метода и общий экземпляр MockingProgressкласса, чтобы определить, предназначен ли вызов метода в макете для заглушки или воспроизведения существующего заглушенного поведения, а не для передачи информации о заглушке через возвращаемое значение издевательский метод.
Ниже представлен мини-анализ кода mockito за пару минут. Обратите внимание: это очень приблизительное описание - здесь задействовано много деталей. Предлагаю вам самому проверить исходники на 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который обрабатывает создание макета. Ключевые части используемой «магии mockito» используются MethodInterceptorдля создания mock: mockito 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экземпляра вызывается метод .