Remove proxyTargetAware attribute from @MockitoSpyBean
This commit removes the proxyTargetAware attribute from @MockitoSpyBean while keeping the underlying feature in tact (i.e., transparent verification for spies created via @MockitoSpyBean). Closes gh-33775
This commit is contained in:
parent
20d21a8251
commit
5bf179b851
|
@ -17,7 +17,6 @@
|
|||
package org.springframework.test.context.bean.override.mockito;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.beans.factory.config.SingletonBeanRegistry;
|
||||
import org.springframework.core.ResolvableType;
|
||||
|
@ -38,15 +37,12 @@ abstract class AbstractMockitoBeanOverrideHandler extends BeanOverrideHandler {
|
|||
|
||||
private final MockReset reset;
|
||||
|
||||
private final boolean proxyTargetAware;
|
||||
|
||||
|
||||
protected AbstractMockitoBeanOverrideHandler(Field field, ResolvableType beanType, @Nullable String beanName,
|
||||
BeanOverrideStrategy strategy, @Nullable MockReset reset, boolean proxyTargetAware) {
|
||||
protected AbstractMockitoBeanOverrideHandler(Field field, ResolvableType beanType,
|
||||
@Nullable String beanName, BeanOverrideStrategy strategy, @Nullable MockReset reset) {
|
||||
|
||||
super(field, beanType, beanName, strategy);
|
||||
this.reset = (reset != null ? reset : MockReset.AFTER);
|
||||
this.proxyTargetAware = proxyTargetAware;
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,14 +54,6 @@ abstract class AbstractMockitoBeanOverrideHandler extends BeanOverrideHandler {
|
|||
return this.reset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if AOP advised beans should be proxy target aware.
|
||||
* @return if proxy target aware
|
||||
*/
|
||||
boolean isProxyTargetAware() {
|
||||
return this.proxyTargetAware;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void trackOverrideInstance(Object mock, SingletonBeanRegistry trackingBeanRegistry) {
|
||||
getMockitoBeans(trackingBeanRegistry).add(mock);
|
||||
|
@ -90,12 +78,12 @@ abstract class AbstractMockitoBeanOverrideHandler extends BeanOverrideHandler {
|
|||
return true;
|
||||
}
|
||||
return (other instanceof AbstractMockitoBeanOverrideHandler that && super.equals(that) &&
|
||||
(this.reset == that.reset) && (this.proxyTargetAware == that.proxyTargetAware));
|
||||
this.reset == that.reset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode() + Objects.hash(this.reset, this.proxyTargetAware);
|
||||
return super.hashCode() + this.reset.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -106,7 +94,6 @@ abstract class AbstractMockitoBeanOverrideHandler extends BeanOverrideHandler {
|
|||
.append("beanName", getBeanName())
|
||||
.append("strategy", getStrategy())
|
||||
.append("reset", getReset())
|
||||
.append("proxyTargetAware", isProxyTargetAware())
|
||||
.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ class MockitoBeanOverrideHandler extends AbstractMockitoBeanOverrideHandler {
|
|||
BeanOverrideStrategy strategy, MockReset reset, Class<?>[] extraInterfaces, @Nullable Answers answers,
|
||||
boolean serializable) {
|
||||
|
||||
super(field, typeToMock, beanName, strategy, reset, false);
|
||||
super(field, typeToMock, beanName, strategy, reset);
|
||||
Assert.notNull(typeToMock, "'typeToMock' must not be null");
|
||||
this.extraInterfaces = asClassSet(extraInterfaces);
|
||||
this.answers = (answers != null ? answers : Answers.RETURNS_DEFAULTS);
|
||||
|
|
|
@ -22,8 +22,6 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.test.context.bean.override.BeanOverride;
|
||||
|
||||
|
@ -87,17 +85,4 @@ public @interface MockitoSpyBean {
|
|||
*/
|
||||
MockReset reset() default MockReset.AFTER;
|
||||
|
||||
/**
|
||||
* Indicates that Mockito methods such as {@link Mockito#verify(Object)
|
||||
* verify(mock)} should use the {@code target} of AOP advised beans,
|
||||
* rather than the proxy itself.
|
||||
* <p>Defaults to {@code true}.
|
||||
* <p>If set to {@code false} you may need to use the result of
|
||||
* {@link org.springframework.test.util.AopTestUtils#getUltimateTargetObject(Object)
|
||||
* AopTestUtils.getUltimateTargetObject(...)} when calling Mockito methods.
|
||||
* @return {@code true} if the target of AOP advised beans is used, or
|
||||
* {@code false} if the proxy is used directly
|
||||
*/
|
||||
boolean proxyTargetAware() default true;
|
||||
|
||||
}
|
||||
|
|
|
@ -39,19 +39,24 @@ import org.springframework.util.StringUtils;
|
|||
* @author Phillip Webb
|
||||
* @author Simon Baslé
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @since 6.2
|
||||
*/
|
||||
class MockitoSpyBeanOverrideHandler extends AbstractMockitoBeanOverrideHandler {
|
||||
|
||||
private static final VerificationStartedListener verificationStartedListener =
|
||||
new SpringAopBypassingVerificationStartedListener();
|
||||
|
||||
|
||||
MockitoSpyBeanOverrideHandler(Field field, ResolvableType typeToSpy, MockitoSpyBean spyAnnotation) {
|
||||
this(field, typeToSpy, (StringUtils.hasText(spyAnnotation.name()) ? spyAnnotation.name() : null),
|
||||
spyAnnotation.reset(), spyAnnotation.proxyTargetAware());
|
||||
spyAnnotation.reset());
|
||||
}
|
||||
|
||||
MockitoSpyBeanOverrideHandler(Field field, ResolvableType typeToSpy, @Nullable String beanName,
|
||||
MockReset reset, boolean proxyTargetAware) {
|
||||
MockReset reset) {
|
||||
|
||||
super(field, typeToSpy, beanName, BeanOverrideStrategy.WRAP, reset, proxyTargetAware);
|
||||
super(field, typeToSpy, beanName, BeanOverrideStrategy.WRAP, reset);
|
||||
Assert.notNull(typeToSpy, "typeToSpy must not be null");
|
||||
}
|
||||
|
||||
|
@ -77,9 +82,7 @@ class MockitoSpyBeanOverrideHandler extends AbstractMockitoBeanOverrideHandler {
|
|||
if (StringUtils.hasLength(name)) {
|
||||
settings.name(name);
|
||||
}
|
||||
if (isProxyTargetAware()) {
|
||||
settings.verificationStartedListeners(new SpringAopBypassingVerificationStartedListener());
|
||||
}
|
||||
settings.verificationStartedListeners(verificationStartedListener);
|
||||
Class<?> toSpy;
|
||||
if (Proxy.isProxyClass(instance.getClass())) {
|
||||
settings.defaultAnswer(AdditionalAnswers.delegatesTo(instance));
|
||||
|
|
|
@ -34,50 +34,45 @@ class MockitoBeanContextCustomizerEqualityTests {
|
|||
|
||||
@Test
|
||||
void contextCustomizerWithSameMockByNameInDifferentClassIsEqual() {
|
||||
assertThat(createContextCustomizer(Case1ByName.class)).isEqualTo(createContextCustomizer(Case2ByName.class));
|
||||
assertThat(customizerFor(Case1ByName.class)).isEqualTo(customizerFor(Case2ByName.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextCustomizerWithSameMockByTypeInDifferentClassIsEqual() {
|
||||
assertThat(createContextCustomizer(Case1ByType.class)).isEqualTo(createContextCustomizer(Case2ByTypeSameFieldName.class));
|
||||
assertThat(customizerFor(Case1ByType.class)).isEqualTo(customizerFor(Case2ByTypeSameFieldName.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextCustomizerWithSameMockByTypeAndDifferentFieldNamesAreNotEqual() {
|
||||
assertThat(createContextCustomizer(Case1ByType.class)).isNotEqualTo(createContextCustomizer(Case2ByType.class));
|
||||
assertThat(customizerFor(Case1ByType.class)).isNotEqualTo(customizerFor(Case2ByType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextCustomizerWithSameSpyByNameInDifferentClassIsEqual() {
|
||||
assertThat(createContextCustomizer(Case4ByName.class)).isEqualTo(createContextCustomizer(Case5ByName.class));
|
||||
assertThat(customizerFor(Case4ByName.class)).isEqualTo(customizerFor(Case5ByName.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextCustomizerWithSameSpyByTypeInDifferentClassIsEqual() {
|
||||
assertThat(createContextCustomizer(Case4ByType.class)).isEqualTo(createContextCustomizer(Case5ByTypeSameFieldName.class));
|
||||
assertThat(customizerFor(Case4ByType.class)).isEqualTo(customizerFor(Case5ByTypeSameFieldName.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextCustomizerWithSameSpyByTypeAndDifferentFieldNamesAreNotEqual() {
|
||||
assertThat(createContextCustomizer(Case4ByType.class)).isNotEqualTo(createContextCustomizer(Case5ByType.class));
|
||||
assertThat(customizerFor(Case4ByType.class)).isNotEqualTo(customizerFor(Case5ByType.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextCustomizerWithSimilarMockButDifferentAnswersIsNotEqual() {
|
||||
assertThat(createContextCustomizer(Case1ByType.class)).isNotEqualTo(createContextCustomizer(Case3.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextCustomizerWithSimilarSpyButDifferentProxyTargetClassFlagIsNotEqual() {
|
||||
assertThat(createContextCustomizer(Case5ByType.class)).isNotEqualTo(createContextCustomizer(Case6.class));
|
||||
assertThat(customizerFor(Case1ByType.class)).isNotEqualTo(customizerFor(Case3.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextCustomizerWithMockAndSpyAreNotEqual() {
|
||||
assertThat(createContextCustomizer(Case1ByType.class)).isNotEqualTo(createContextCustomizer(Case4ByType.class));
|
||||
assertThat(customizerFor(Case1ByType.class)).isNotEqualTo(customizerFor(Case4ByType.class));
|
||||
}
|
||||
|
||||
private ContextCustomizer createContextCustomizer(Class<?> testClass) {
|
||||
private ContextCustomizer customizerFor(Class<?> testClass) {
|
||||
ContextCustomizer customizer = BeanOverrideContextCustomizerTestUtils.createContextCustomizer(testClass);
|
||||
assertThat(customizer).isNotNull();
|
||||
return customizer;
|
||||
|
@ -160,11 +155,4 @@ class MockitoBeanContextCustomizerEqualityTests {
|
|||
|
||||
}
|
||||
|
||||
static class Case6 {
|
||||
|
||||
@MockitoSpyBean(proxyTargetAware = false)
|
||||
private String serviceToMock;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -49,63 +49,46 @@ class MockitoSpyBeanOverrideHandlerTests {
|
|||
|
||||
@Test
|
||||
void isEqualToWithSameInstance() {
|
||||
MockitoSpyBeanOverrideHandler handler = createBeanOverrideHandler(sampleField("service"));
|
||||
MockitoSpyBeanOverrideHandler handler = handlerFor("service");
|
||||
assertThat(handler).isEqualTo(handler);
|
||||
assertThat(handler).hasSameHashCodeAs(handler);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToWithSameMetadata() {
|
||||
MockitoSpyBeanOverrideHandler handler1 = createBeanOverrideHandler(sampleField("service"));
|
||||
MockitoSpyBeanOverrideHandler handler2 = createBeanOverrideHandler(sampleField("service"));
|
||||
MockitoSpyBeanOverrideHandler handler1 = handlerFor("service");
|
||||
MockitoSpyBeanOverrideHandler handler2 = handlerFor("service");
|
||||
assertThat(handler1).isEqualTo(handler2);
|
||||
assertThat(handler1).hasSameHashCodeAs(handler2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToByTypeLookupWithSameMetadataButDifferentField() {
|
||||
MockitoSpyBeanOverrideHandler handler1 = createBeanOverrideHandler(sampleField("service"));
|
||||
MockitoSpyBeanOverrideHandler handler2 = createBeanOverrideHandler(sampleField("service2"));
|
||||
assertThat(handler1).isNotEqualTo(handler2);
|
||||
assertThat(handlerFor("service")).isNotEqualTo(handlerFor("service2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualToByNameLookupWithSameMetadataButDifferentField() {
|
||||
MockitoSpyBeanOverrideHandler handler1 = createBeanOverrideHandler(sampleField("service3"));
|
||||
MockitoSpyBeanOverrideHandler handler2 = createBeanOverrideHandler(sampleField("service4"));
|
||||
MockitoSpyBeanOverrideHandler handler1 = handlerFor("service3");
|
||||
MockitoSpyBeanOverrideHandler handler2 = handlerFor("service4");
|
||||
assertThat(handler1).isEqualTo(handler2);
|
||||
assertThat(handler1).hasSameHashCodeAs(handler2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWithSameMetadataButDifferentBeanName() {
|
||||
MockitoSpyBeanOverrideHandler handler1 = createBeanOverrideHandler(sampleField("service"));
|
||||
MockitoSpyBeanOverrideHandler handler2 = createBeanOverrideHandler(sampleField("service3"));
|
||||
assertThat(handler1).isNotEqualTo(handler2);
|
||||
assertThat(handlerFor("service")).isNotEqualTo(handlerFor("service3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWithSameMetadataButDifferentReset() {
|
||||
MockitoSpyBeanOverrideHandler handler1 = createBeanOverrideHandler(sampleField("service"));
|
||||
MockitoSpyBeanOverrideHandler handler2 = createBeanOverrideHandler(sampleField("service5"));
|
||||
assertThat(handler1).isNotEqualTo(handler2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void isNotEqualToWithSameMetadataButDifferentProxyTargetAwareFlag() {
|
||||
MockitoSpyBeanOverrideHandler handler1 = createBeanOverrideHandler(sampleField("service"));
|
||||
MockitoSpyBeanOverrideHandler handler2 = createBeanOverrideHandler(sampleField("service6"));
|
||||
assertThat(handler1).isNotEqualTo(handler2);
|
||||
assertThat(handlerFor("service")).isNotEqualTo(handlerFor("service5"));
|
||||
}
|
||||
|
||||
|
||||
private Field sampleField(String fieldName) {
|
||||
private static MockitoSpyBeanOverrideHandler handlerFor(String fieldName) {
|
||||
Field field = ReflectionUtils.findField(Sample.class, fieldName);
|
||||
assertThat(field).isNotNull();
|
||||
return field;
|
||||
}
|
||||
|
||||
private MockitoSpyBeanOverrideHandler createBeanOverrideHandler(Field field) {
|
||||
MockitoSpyBean annotation = AnnotatedElementUtils.getMergedAnnotation(field, MockitoSpyBean.class);
|
||||
return new MockitoSpyBeanOverrideHandler(field, ResolvableType.forClass(field.getType()), annotation);
|
||||
}
|
||||
|
@ -142,9 +125,6 @@ class MockitoSpyBeanOverrideHandlerTests {
|
|||
@MockitoSpyBean(reset = MockReset.BEFORE)
|
||||
private String service5;
|
||||
|
||||
@MockitoSpyBean(proxyTargetAware = false)
|
||||
private String service6;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue