-
Notifications
You must be signed in to change notification settings - Fork 38.6k
Closed
Labels
Milestone
Description
Overview
SpringAopBypassingVerificationStartedListener
provides partial support for transparent verification for Mockito spies created via @MockitoSpyBean
when the spy is wrapped in a Spring AOP proxy.
However, the following @Disabled
test currently fails since the AOP proxy for the DateService
is not considered a mock by Mockito.
Lines 88 to 117 in 982f7f8
/** | |
* Verification for a Mockito spy that is wrapped in a Spring AOP proxy should | |
* always work when performed via the Spring AOP proxy. However, stubbing | |
* does not currently work via the Spring AOP proxy. | |
* | |
* <p>Consequently, this test method supplies the ultimate target of the Spring | |
* AOP proxy to stubbing calls, while supplying the Spring AOP proxy to verification | |
* calls. | |
*/ | |
@Disabled("Disabled until transparent verification for @MockitoSpyBean is implemented") | |
@Test | |
void stubOnUltimateTargetAndVerifyOnSpringAopProxy() { | |
assertThat(AopUtils.isAopProxy(dateService)).as("is Spring AOP proxy").isTrue(); | |
DateService spy = AopTestUtils.getUltimateTargetObject(dateService); | |
assertThat(Mockito.mockingDetails(spy).isSpy()).as("ultimate target is Mockito spy").isTrue(); | |
given(spy.getDate(false)).willReturn(1L); | |
Long date = dateService.getDate(false); | |
assertThat(date).isOne(); | |
given(spy.getDate(false)).willReturn(2L); | |
date = dateService.getDate(false); | |
assertThat(date).isEqualTo(1L); // 1L instead of 2L, because the AOP proxy caches the original value. | |
// Each of the following verifies times(1), because the AOP proxy caches the | |
// original value and does not delegate to the spy on subsequent invocations. | |
verify(dateService, times(1)).getDate(false); | |
verify(dateService, times(1)).getDate(eq(false)); | |
verify(dateService, times(1)).getDate(anyBoolean()); | |
} |
To provide transparent verification support for @MockitoSpyBean
, we need to implement and register a Mockito MockResolver
, analogous to the SpringBootMockResolver
in Spring Boot.
Related Issues
- AopTestUtils.getUltimateTargetObject results in stack overflow for proxy backed by LazyInitTargetSource #29215 (comment)
- SpringBootMockResolver causes AopTestUtils.getUltimateTargetObject to recurse until the stack overflows when it calls it with Spring Security's authentication manager bean spring-boot#32632
- Allow proxied @SpyBeans to be used with Mockito's inline mock maker spring-boot#22416
- mockito3.4.0 InlineByteBuddyMockMaker can't work with spring cglib proxy, but ByteBuddyMockMaker works mockito/mockito#1980