-
Notifications
You must be signed in to change notification settings - Fork 38.8k
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