Polish bean override internals
This commit is contained in:
parent
c832d5f496
commit
6c2cba5d8a
|
@ -35,7 +35,6 @@ import org.springframework.test.context.bean.override.BeanOverrideStrategy;
|
|||
import org.springframework.test.context.bean.override.OverrideMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
|
@ -43,13 +42,14 @@ import org.springframework.util.StringUtils;
|
|||
*
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @since 6.2
|
||||
*/
|
||||
class MockitoBeanOverrideMetadata extends MockitoOverrideMetadata {
|
||||
|
||||
private final Set<Class<?>> extraInterfaces;
|
||||
|
||||
private final Answers answer;
|
||||
private final Answers answers;
|
||||
|
||||
private final boolean serializable;
|
||||
|
||||
|
@ -59,21 +59,22 @@ class MockitoBeanOverrideMetadata extends MockitoOverrideMetadata {
|
|||
annotation.reset(), annotation.extraInterfaces(), annotation.answers(), annotation.serializable());
|
||||
}
|
||||
|
||||
MockitoBeanOverrideMetadata(Field field, ResolvableType typeToMock, @Nullable String beanName, MockReset reset,
|
||||
Class<?>[] extraInterfaces, @Nullable Answers answer, boolean serializable) {
|
||||
private MockitoBeanOverrideMetadata(Field field, ResolvableType typeToMock, @Nullable String beanName, MockReset reset,
|
||||
Class<?>[] extraInterfaces, @Nullable Answers answers, boolean serializable) {
|
||||
|
||||
super(field, typeToMock, beanName, BeanOverrideStrategy.REPLACE_OR_CREATE_DEFINITION, reset, false);
|
||||
Assert.notNull(typeToMock, "'typeToMock' must not be null");
|
||||
this.extraInterfaces = asClassSet(extraInterfaces);
|
||||
this.answer = (answer != null) ? answer : Answers.RETURNS_DEFAULTS;
|
||||
this.answers = (answers != null ? answers : Answers.RETURNS_DEFAULTS);
|
||||
this.serializable = serializable;
|
||||
}
|
||||
|
||||
private static Set<Class<?>> asClassSet(@Nullable Class<?>[] classes) {
|
||||
Set<Class<?>> classSet = new LinkedHashSet<>();
|
||||
if (classes != null) {
|
||||
classSet.addAll(Arrays.asList(classes));
|
||||
|
||||
private static Set<Class<?>> asClassSet(Class<?>[] classes) {
|
||||
if (classes.length == 0) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<Class<?>> classSet = new LinkedHashSet<>(Arrays.asList(classes));
|
||||
return Collections.unmodifiableSet(classSet);
|
||||
}
|
||||
|
||||
|
@ -90,12 +91,12 @@ class MockitoBeanOverrideMetadata extends MockitoOverrideMetadata {
|
|||
* Return the {@link Answers}.
|
||||
* @return the answers mode
|
||||
*/
|
||||
Answers getAnswer() {
|
||||
return this.answer;
|
||||
Answers getAnswers() {
|
||||
return this.answers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if the mock is serializable.
|
||||
* Determine if the mock is serializable.
|
||||
* @return {@code true} if the mock is serializable
|
||||
*/
|
||||
boolean isSerializable() {
|
||||
|
@ -108,7 +109,7 @@ class MockitoBeanOverrideMetadata extends MockitoOverrideMetadata {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T createMock(String name) {
|
||||
private <T> T createMock(String name) {
|
||||
MockSettings settings = MockReset.withSettings(getReset());
|
||||
if (StringUtils.hasLength(name)) {
|
||||
settings.name(name);
|
||||
|
@ -116,7 +117,7 @@ class MockitoBeanOverrideMetadata extends MockitoOverrideMetadata {
|
|||
if (!this.extraInterfaces.isEmpty()) {
|
||||
settings.extraInterfaces(ClassUtils.toClassArray(this.extraInterfaces));
|
||||
}
|
||||
settings.defaultAnswer(this.answer);
|
||||
settings.defaultAnswer(this.answers);
|
||||
if (this.serializable) {
|
||||
settings.serializable();
|
||||
}
|
||||
|
@ -132,27 +133,26 @@ class MockitoBeanOverrideMetadata extends MockitoOverrideMetadata {
|
|||
if (other == null || other.getClass() != getClass()) {
|
||||
return false;
|
||||
}
|
||||
MockitoBeanOverrideMetadata that = (MockitoBeanOverrideMetadata) other;
|
||||
boolean result = super.equals(that);
|
||||
result = result && ObjectUtils.nullSafeEquals(this.extraInterfaces, that.extraInterfaces);
|
||||
result = result && ObjectUtils.nullSafeEquals(this.answer, that.answer);
|
||||
result = result && this.serializable == that.serializable;
|
||||
return result;
|
||||
return (other instanceof MockitoBeanOverrideMetadata that && super.equals(that) &&
|
||||
(this.serializable == that.serializable) && (this.answers == that.answers) &&
|
||||
Objects.equals(this.extraInterfaces, that.extraInterfaces));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.extraInterfaces, this.answer, this.serializable) + super.hashCode();
|
||||
return super.hashCode() + Objects.hash(this.extraInterfaces, this.answers, this.serializable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringCreator(this)
|
||||
.append("field", getField())
|
||||
.append("beanType", getBeanType())
|
||||
.append("beanName", getBeanName())
|
||||
.append("strategy", getStrategy())
|
||||
.append("reset", getReset())
|
||||
.append("extraInterfaces", getExtraInterfaces())
|
||||
.append("answer", getAnswer())
|
||||
.append("answers", getAnswers())
|
||||
.append("serializable", isSerializable())
|
||||
.toString();
|
||||
}
|
||||
|
|
|
@ -17,16 +17,18 @@
|
|||
package org.springframework.test.context.bean.override.mockito;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.mockito.Mockito;
|
||||
|
||||
/**
|
||||
* Beans created using Mockito.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Sam Brannen
|
||||
* @since 6.2
|
||||
*/
|
||||
class MockitoBeans implements Iterable<Object> {
|
||||
class MockitoBeans {
|
||||
|
||||
private final List<Object> beans = new ArrayList<>();
|
||||
|
||||
|
@ -35,9 +37,8 @@ class MockitoBeans implements Iterable<Object> {
|
|||
this.beans.add(bean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Object> iterator() {
|
||||
return this.beans.iterator();
|
||||
void resetAll() {
|
||||
this.beans.forEach(Mockito::reset);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,16 +22,17 @@ import java.util.Objects;
|
|||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.SingletonBeanRegistry;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.test.context.bean.override.BeanOverrideStrategy;
|
||||
import org.springframework.test.context.bean.override.OverrideMetadata;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Base {@link OverrideMetadata} implementation for Mockito.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
* @since 6.2
|
||||
*/
|
||||
abstract class MockitoOverrideMetadata extends OverrideMetadata {
|
||||
|
@ -45,7 +46,7 @@ abstract class MockitoOverrideMetadata extends OverrideMetadata {
|
|||
BeanOverrideStrategy strategy, @Nullable MockReset reset, boolean proxyTargetAware) {
|
||||
|
||||
super(field, beanType, beanName, strategy);
|
||||
this.reset = (reset != null) ? reset : MockReset.AFTER;
|
||||
this.reset = (reset != null ? reset : MockReset.AFTER);
|
||||
this.proxyTargetAware = proxyTargetAware;
|
||||
}
|
||||
|
||||
|
@ -73,10 +74,9 @@ abstract class MockitoOverrideMetadata extends OverrideMetadata {
|
|||
tracker = (MockitoBeans) trackingBeanRegistry.getSingleton(MockitoBeans.class.getName());
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ignored) {
|
||||
|
||||
}
|
||||
if (tracker == null) {
|
||||
tracker= new MockitoBeans();
|
||||
tracker = new MockitoBeans();
|
||||
trackingBeanRegistry.registerSingleton(MockitoBeans.class.getName(), tracker);
|
||||
}
|
||||
tracker.add(mock);
|
||||
|
@ -87,19 +87,25 @@ abstract class MockitoOverrideMetadata extends OverrideMetadata {
|
|||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
if (other == null || !getClass().isAssignableFrom(other.getClass())) {
|
||||
return false;
|
||||
}
|
||||
MockitoOverrideMetadata that = (MockitoOverrideMetadata) other;
|
||||
boolean result = super.equals(that);
|
||||
result = result && ObjectUtils.nullSafeEquals(this.reset, that.reset);
|
||||
result = result && ObjectUtils.nullSafeEquals(this.proxyTargetAware, that.proxyTargetAware);
|
||||
return result;
|
||||
return (other instanceof MockitoOverrideMetadata that && super.equals(that) &&
|
||||
(this.reset == that.reset) && (this.proxyTargetAware == that.proxyTargetAware));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.reset, this.proxyTargetAware) + super.hashCode();
|
||||
return super.hashCode() + Objects.hash(this.reset, this.proxyTargetAware);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringCreator(this)
|
||||
.append("field", getField())
|
||||
.append("beanType", getBeanType())
|
||||
.append("beanName", getBeanName())
|
||||
.append("strategy", getStrategy())
|
||||
.append("reset", getReset())
|
||||
.append("proxyTargetAware", isProxyTargetAware())
|
||||
.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -87,12 +87,7 @@ public class MockitoResetTestExecutionListener extends AbstractTestExecutionList
|
|||
}
|
||||
}
|
||||
try {
|
||||
MockitoBeans mockedBeans = beanFactory.getBean(MockitoBeans.class);
|
||||
for (Object mockedBean : mockedBeans) {
|
||||
if (reset.equals(MockReset.get(mockedBean))) {
|
||||
Mockito.reset(mockedBean);
|
||||
}
|
||||
}
|
||||
beanFactory.getBean(MockitoBeans.class).resetAll();
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
// Continue
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.mockito.listeners.VerificationStartedListener;
|
|||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.test.context.bean.override.BeanOverrideStrategy;
|
||||
import org.springframework.test.context.bean.override.OverrideMetadata;
|
||||
|
@ -68,8 +67,7 @@ class MockitoSpyBeanOverrideMetadata extends MockitoOverrideMetadata {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T createSpy(String name, Object instance) {
|
||||
Assert.notNull(instance, "Instance must not be null");
|
||||
private <T> T createSpy(String name, Object instance) {
|
||||
Class<?> resolvedTypeToOverride = getBeanType().resolve();
|
||||
Assert.notNull(resolvedTypeToOverride, "Failed to resolve type to override");
|
||||
Assert.isInstanceOf(resolvedTypeToOverride, instance);
|
||||
|
@ -96,15 +94,6 @@ class MockitoSpyBeanOverrideMetadata extends MockitoOverrideMetadata {
|
|||
return (T) Mockito.mock(toSpy, settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringCreator(this)
|
||||
.append("beanName", getBeanName())
|
||||
.append("beanType", getBeanType())
|
||||
.append("reset", getReset())
|
||||
.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A {@link VerificationStartedListener} that bypasses any proxy created by
|
||||
|
|
|
@ -56,22 +56,14 @@ public class MockitoBeanForByNameLookupIntegrationTests {
|
|||
|
||||
|
||||
@Test
|
||||
void fieldHasOverride(ApplicationContext ctx) {
|
||||
assertThat(ctx.getBean("field"))
|
||||
.isInstanceOf(ExampleService.class)
|
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isMock()).as("isMock").isTrue())
|
||||
.isSameAs(this.field);
|
||||
|
||||
assertThat(this.field.greeting()).as("mocked greeting").isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void renamedFieldHasOverride(ApplicationContext ctx) {
|
||||
void fieldAndRenamedFieldHaveSameOverride(ApplicationContext ctx) {
|
||||
assertThat(ctx.getBean("field"))
|
||||
.isInstanceOf(ExampleService.class)
|
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isMock()).as("isMock").isTrue())
|
||||
.isSameAs(this.field)
|
||||
.isSameAs(this.renamed1);
|
||||
|
||||
assertThat(this.field.greeting()).as("mocked greeting").isNull();
|
||||
assertThat(this.renamed1.greeting()).as("mocked greeting").isNull();
|
||||
}
|
||||
|
||||
|
@ -91,18 +83,11 @@ public class MockitoBeanForByNameLookupIntegrationTests {
|
|||
public class MockitoBeanNestedTests {
|
||||
|
||||
@Test
|
||||
void fieldHasOverride(ApplicationContext ctx) {
|
||||
assertThat(ctx.getBean("nestedField"))
|
||||
.isInstanceOf(ExampleService.class)
|
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isMock()).as("isMock").isTrue())
|
||||
.isSameAs(nestedField);
|
||||
}
|
||||
|
||||
@Test
|
||||
void renamedFieldHasOverride(ApplicationContext ctx) {
|
||||
void fieldAndRenamedFieldHaveSameOverride(ApplicationContext ctx) {
|
||||
assertThat(ctx.getBean("nestedField"))
|
||||
.isInstanceOf(ExampleService.class)
|
||||
.satisfies(o -> assertThat(Mockito.mockingDetails(o).isMock()).as("isMock").isTrue())
|
||||
.isSameAs(nestedField)
|
||||
.isSameAs(renamed2);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue