Короткий ответ заключается в том, что в вашем примере результатом 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
экземпляра вызывается метод .