Ensure argument matchers work with AOP spies

Update MockitoAopProxyTargetInterceptor to deal with deal with any
existing argument matchers when working with the VerificationMode.

Prior to this commit `@SpyBean` when combined with AOP could not support
argument matchers.

Fixes gh-6871
This commit is contained in:
Phillip Webb 2016-09-12 14:53:07 -07:00
parent 41a36c4d40
commit 3684c2ec56
4 changed files with 39 additions and 15 deletions

View File

@ -17,12 +17,15 @@
package org.springframework.boot.test.mock.mockito;
import java.lang.reflect.Field;
import java.util.List;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.Interceptor;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.mockito.internal.InternalMockHandler;
import org.mockito.internal.matchers.LocalizedMatcher;
import org.mockito.internal.progress.ArgumentMatcherStorage;
import org.mockito.internal.progress.MockingProgress;
import org.mockito.internal.stubbing.InvocationContainer;
import org.mockito.internal.util.MockUtil;
@ -107,7 +110,7 @@ class MockitoAopProxyTargetInterceptor implements MethodInterceptor {
synchronized (this.monitor) {
VerificationMode mode = this.progress.pullVerificationMode();
if (mode != null) {
this.progress.verificationStarted(mode);
resetVerificationStarted(mode);
return true;
}
return false;
@ -124,11 +127,20 @@ class MockitoAopProxyTargetInterceptor implements MethodInterceptor {
mode = new MockAwareVerificationMode(target, mockAwareMode);
}
}
this.progress.verificationStarted(mode);
resetVerificationStarted(mode);
}
}
}
private void resetVerificationStarted(VerificationMode mode) {
ArgumentMatcherStorage storage = this.progress.getArgumentMatcherStorage();
List<LocalizedMatcher> matchers = storage.pullLocalizedMatchers();
this.progress.verificationStarted(mode);
for (LocalizedMatcher matcher : matchers) {
storage.reportMatcher(matcher);
}
}
}
}

View File

@ -35,6 +35,8 @@ import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@ -52,13 +54,15 @@ public class MockBeanWithAopProxyTests {
@Test
public void verifyShouldUseProxyTarget() throws Exception {
given(this.dateService.getDate()).willReturn(1L);
Long d1 = this.dateService.getDate();
given(this.dateService.getDate(false)).willReturn(1L);
Long d1 = this.dateService.getDate(false);
assertThat(d1).isEqualTo(1L);
given(this.dateService.getDate()).willReturn(2L);
Long d2 = this.dateService.getDate();
given(this.dateService.getDate(false)).willReturn(2L);
Long d2 = this.dateService.getDate(false);
assertThat(d2).isEqualTo(2L);
verify(this.dateService, times(2)).getDate();
verify(this.dateService, times(2)).getDate(false);
verify(this.dateService, times(2)).getDate(eq(false));
verify(this.dateService, times(2)).getDate(anyBoolean());
}
@Configuration
@ -86,7 +90,7 @@ public class MockBeanWithAopProxyTests {
static class DateService {
@Cacheable(cacheNames = "test")
public Long getDate() {
public Long getDate(boolean argument) {
return System.nanoTime();
}

View File

@ -34,6 +34,8 @@ import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Service;
import org.springframework.test.context.junit4.SpringRunner;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@ -52,8 +54,10 @@ public class SpyBeanWithAopProxyAndNotProxyTargetAwareTests {
@Test(expected = UnfinishedVerificationException.class)
public void verifyShouldUseProxyTarget() throws Exception {
this.dateService.getDate();
verify(this.dateService, times(1)).getDate();
this.dateService.getDate(false);
verify(this.dateService, times(1)).getDate(false);
verify(this.dateService, times(1)).getDate(eq(false));
verify(this.dateService, times(1)).getDate(anyBoolean());
reset(this.dateService);
}
@ -82,7 +86,7 @@ public class SpyBeanWithAopProxyAndNotProxyTargetAwareTests {
static class DateService {
@Cacheable(cacheNames = "test")
public Long getDate() {
public Long getDate(boolean arg) {
return System.nanoTime();
}

View File

@ -34,6 +34,8 @@ import org.springframework.stereotype.Service;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@ -51,11 +53,13 @@ public class SpyBeanWithAopProxyTests {
@Test
public void verifyShouldUseProxyTarget() throws Exception {
Long d1 = this.dateService.getDate();
Long d1 = this.dateService.getDate(false);
Thread.sleep(200);
Long d2 = this.dateService.getDate();
Long d2 = this.dateService.getDate(false);
assertThat(d1).isEqualTo(d2);
verify(this.dateService, times(1)).getDate();
verify(this.dateService, times(1)).getDate(false);
verify(this.dateService, times(1)).getDate(eq(false));
verify(this.dateService, times(1)).getDate(anyBoolean());
}
@Configuration
@ -83,7 +87,7 @@ public class SpyBeanWithAopProxyTests {
static class DateService {
@Cacheable(cacheNames = "test")
public Long getDate() {
public Long getDate(boolean arg) {
return System.nanoTime();
}