Это ожидается. Mockito создает шпиона путем создания мелкой копии , а ссылка на метод this::add2
копируется при сохранении ссылки на старую this
.
TestService myTestService = new TestService();
TestService mySpy = Mockito.spy(myTestService);
В этом примере mySpy
является экземпляром сгенерированного подкласса TestService , у которого все переопределяемые методы переопределяются для делегирования в Mockito, а все его состояния экземпляра копируются из myTestService
. Это означает, что myTestService.mapping == mySpy.mapping
, что также означает, что ссылка на this
(что означает myTestService
), захваченная в функции, скопирована.
Ссылки на методы, примененные к экземпляру, захватывают этот экземпляр, как на странице Oracle в разделе Ссылки на методы в разделе «Виды ссылок на методы». Объект, который получает вызов add2
, является оригиналом, а не шпионом, поэтому вы получаете исходное поведение (4), а не поведение, на которое влияет шпион (6).
Это должно быть несколько интуитивно понятно: вы можете вызывать Function<Integer, Integer>
, не передавая экземпляр TestService, поэтому вполне разумно, чтобы функция содержала неявную ссылку на реализацию TestService. Вы наблюдаете это поведение, потому что у экземпляра шпиона его состояние скопировано из реального экземпляра после . Функция инициализирована и this
сохранено.
Рассмотрим эту альтернативу, которую вы можете определить в TestService:
BiFunction<TestService, Integer, Integer> mapping2 = TestService::add2;
Здесь функция mapping2
не применяется к конкретному объекту, но вместо этого применяется к любому переданному экземпляру TestService. Следовательно, ваш тест вызовет это:
@Test
public void mockitoTest2(){
doReturn(6).when(testService).add2(2);
System.out.println(testService.mapping2.apply(testService, 2));
}
... и поскольку вы передаете шпиона testService
, он будет обрабатывать вызов виртуального метода для add2
и вызовет поведение, установленное для шпиона (возвращающее 6). Неявно не сохранено this
, поэтому ваша функция работает так, как вы ожидаете.
См. Также: Mockito, управляемый: требуется, но не вызывается?