diff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-beanoverriding.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-beanoverriding.adoc index 29527970032..3639b88fb06 100644 --- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-beanoverriding.adoc +++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-beanoverriding.adoc @@ -48,7 +48,7 @@ Java:: ====== NOTE: The method to invoke is searched in the test class and any enclosing class it might -have, as well as its hierarchy. This typically allows nested test class to provide the +have, as well as its hierarchy. This typically allows nested test class to rely on the method to use in the root test class. [[spring-testing-annotation-beanoverriding-mockitobean]] @@ -101,33 +101,34 @@ Java:: The three annotations introduced above build upon the `@BeanOverride` meta-annotation and associated infrastructure, which allows to define custom bean overriding variants. -In order to provide an extension, three classes are needed: +To create an extension, the following is needed: - - A concrete `BeanOverrideProcessor` implementation, `P`. - - One or more concrete `OverrideMetadata` implementations created by said processor. - - An annotation meta-annotated with `@BeanOverride(P.class)`. +- An annotation meta-annotated with `@BeanOverride` that defines the +`BeanOverrideProcessor` to use. +- The `BeanOverrideProcessor` implementation itself. +- One or more concrete `OverrideMetadata` implementations provided by the processor. The Spring TestContext Framework includes infrastructure classes that support bean -overriding: a `BeanFactoryPostProcessor`, a `TestExecutionListener` and a `ContextCustomizerFactory`. +overriding: a `BeanFactoryPostProcessor`, a `TestExecutionListener` and a +`ContextCustomizerFactory`. The later two are automatically registered via the Spring TestContext Framework `spring.factories` file, and are responsible for setting up the rest of the infrastructure. The test classes are parsed looking for any field meta-annotated with `@BeanOverride`, -instantiating the relevant `BeanOverrideProcessor` in order to register an `OverrideMetadata`. +instantiating the relevant `BeanOverrideProcessor` in order to register an +`OverrideMetadata`. Then the `BeanOverrideBeanFactoryPostProcessor` will use that information to alter the -Context, registering and replacing bean definitions as influenced by each metadata +context, registering and replacing bean definitions as defined by each metadata `BeanOverrideStrategy`: - - `REPLACE_DEFINITION`: the bean post-processor replaces the bean definition. -If it is not present in the context, an exception is thrown. - - `CREATE_OR_REPLACE_DEFINITION`: same as above but if the bean definition is not present -in the context, one is created - - `WRAP_EARLY_BEAN`: an original instance is obtained and passed to the `OverrideMetadata` -when the override instance is created. - -NOTE: The Bean Overriding infrastructure doesn't include any bean resolution step -(unlike e.g. an `@Autowired`-annotated field). As such, the name of the bean to override -MUST be somehow provided to or computed by the `BeanOverrideProcessor`. Typically, the end -user provides the name as part of the custom annotation's attributes, or the annotated -field's name. \ No newline at end of file + - `REPLACE_DEFINITION`: replaces the bean definition. If it is not present in the +context, an exception is thrown. + - `CREATE_OR_REPLACE_DEFINITION`: replaces the bean definition if the bean definition +does not exist, or create one if it is not. + - `WRAP_BEAN`: get the original instance early so that it can be wrapped. + +NOTE: The Bean Overriding infrastructure does not include any bean resolution step, +unlike an `@Autowired`-annotated field for instance. As such, the name of the bean to +override must be somehow provided to or computed by the `BeanOverrideProcessor`. +Typically, the user provides the name one way or the other. \ No newline at end of file diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverride.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverride.java index 2bfd17a7fed..a92c19c9da6 100644 --- a/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverride.java +++ b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverride.java @@ -22,15 +22,13 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Mark an annotation as eligible for Bean Override parsing. + * Mark an annotation as eligible for Bean Override processing. * - *
This meta-annotation specifies a {@link BeanOverrideProcessor} class which - * must be capable of handling the composed annotation that is meta-annotated - * with {@code @BeanOverride}. + *
Specifying this annotation triggers the defined {@link BeanOverrideProcessor} + * which must be capable of handling the composed annotation and its attributes. * - *
The composed annotation that is meta-annotated with {@code @BeanOverride} - * must have a {@code RetentionPolicy} of {@link RetentionPolicy#RUNTIME RUNTIME} - * and a {@code Target} of {@link ElementType#FIELD FIELD}. + *
The composed annotation is meant to be detected on fields only so it is + * expected that it has a {@code Target} of {@link ElementType#FIELD FIELD}. * * @author Simon Baslé * @since 6.2 @@ -41,8 +39,8 @@ import java.lang.annotation.Target; public @interface BeanOverride { /** - * A {@link BeanOverrideProcessor} implementation class by which the composed - * annotation should be processed. + * The {@link BeanOverrideProcessor} implementation to trigger against + * the composed annotation. */ Class extends BeanOverrideProcessor> value(); diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideBeanFactoryPostProcessor.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideBeanFactoryPostProcessor.java index 60f914df6ff..dc52c828b32 100644 --- a/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideBeanFactoryPostProcessor.java +++ b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideBeanFactoryPostProcessor.java @@ -22,31 +22,26 @@ import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; import org.springframework.aop.scope.ScopedProxyUtils; import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.config.ConstructorArgumentValues; -import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor; import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.core.Ordered; import org.springframework.core.PriorityOrdered; import org.springframework.core.ResolvableType; -import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * A {@link BeanFactoryPostProcessor} implementation that processes test classes - * and adapt the {@link BeanDefinitionRegistry} for any {@link BeanOverride} it - * may define. + * and adapt the {@link BeanFactory} for any {@link BeanOverride} it may define. * *
A set of classes from which to parse {@link OverrideMetadata} must be
* provided to this processor. Each test class is expected to use any
@@ -66,10 +61,6 @@ import org.springframework.util.StringUtils;
*/
class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
- private static final String INFRASTRUCTURE_BEAN_NAME = BeanOverrideBeanFactoryPostProcessor.class.getName();
-
- private static final String EARLY_INFRASTRUCTURE_BEAN_NAME =
- BeanOverrideBeanFactoryPostProcessor.WrapEarlyBeanPostProcessor.class.getName();
private final BeanOverrideRegistrar overrideRegistrar;
@@ -94,14 +85,16 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
- Assert.isInstanceOf(DefaultListableBeanFactory.class, beanFactory,
- "Bean overriding annotations can only be used on a DefaultListableBeanFactory");
- postProcessWithRegistry((DefaultListableBeanFactory) beanFactory);
+ if (!(beanFactory instanceof BeanDefinitionRegistry registry)) {
+ throw new IllegalStateException("Cannot process bean override with a BeanFactory " +
+ "that doesn't implement BeanDefinitionRegistry: " + beanFactory.getClass());
+ }
+ postProcessWithRegistry(beanFactory, registry);
}
- private void postProcessWithRegistry(DefaultListableBeanFactory registry) {
+ private void postProcessWithRegistry(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry) {
for (OverrideMetadata metadata : this.overrideRegistrar.getOverrideMetadata()) {
- registerBeanOverride(registry, metadata);
+ registerBeanOverride(beanFactory, registry, metadata);
}
}
@@ -116,15 +109,20 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
to.setScope(from.getScope());
}
- private void registerBeanOverride(DefaultListableBeanFactory beanFactory, OverrideMetadata overrideMetadata) {
+ private void registerBeanOverride(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry,
+ OverrideMetadata overrideMetadata) {
+
switch (overrideMetadata.getStrategy()) {
- case REPLACE_DEFINITION -> registerReplaceDefinition(beanFactory, overrideMetadata, true);
- case REPLACE_OR_CREATE_DEFINITION -> registerReplaceDefinition(beanFactory, overrideMetadata, false);
+ case REPLACE_DEFINITION ->
+ registerReplaceDefinition(beanFactory, registry, overrideMetadata, true);
+ case REPLACE_OR_CREATE_DEFINITION ->
+ registerReplaceDefinition(beanFactory, registry, overrideMetadata, false);
case WRAP_BEAN -> registerWrapBean(beanFactory, overrideMetadata);
}
}
- private void registerReplaceDefinition(DefaultListableBeanFactory beanFactory, OverrideMetadata overrideMetadata, boolean enforceExistingDefinition) {
+ private void registerReplaceDefinition(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry,
+ OverrideMetadata overrideMetadata, boolean enforceExistingDefinition) {
RootBeanDefinition beanDefinition = createBeanDefinition(overrideMetadata);
String beanName = overrideMetadata.getBeanName();
@@ -133,13 +131,13 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
if (beanFactory.containsBeanDefinition(beanName)) {
existingBeanDefinition = beanFactory.getBeanDefinition(beanName);
copyBeanDefinitionDetails(existingBeanDefinition, beanDefinition);
- beanFactory.removeBeanDefinition(beanName);
+ registry.removeBeanDefinition(beanName);
}
else if (enforceExistingDefinition) {
throw new IllegalStateException("Unable to override bean '" + beanName + "'; there is no" +
" bean definition to replace with that name");
}
- beanFactory.registerBeanDefinition(beanName, beanDefinition);
+ registry.registerBeanDefinition(beanName, beanDefinition);
Object override = overrideMetadata.createOverride(beanName, existingBeanDefinition, null);
if (beanFactory.isSingleton(beanName)) {
@@ -160,7 +158,7 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
* upon creation, during the {@link WrapEarlyBeanPostProcessor#getEarlyBeanReference(Object, String)}
* phase.
*/
- private void registerWrapBean(DefaultListableBeanFactory beanFactory, OverrideMetadata metadata) {
+ private void registerWrapBean(ConfigurableListableBeanFactory beanFactory, OverrideMetadata metadata) {
Set Not required when using the Spring TestContext Framework, as registration
- * is automatic via the
- * {@link org.springframework.core.io.support.SpringFactoriesLoader SpringFactoriesLoader}
- * mechanism.
- * @param registry the bean definition registry
- */
- public static void register(BeanDefinitionRegistry registry) {
- RuntimeBeanReference registrarReference = new RuntimeBeanReference(BeanOverrideRegistrar.INFRASTRUCTURE_BEAN_NAME);
- // Early processor
- addInfrastructureBeanDefinition(
- registry, WrapEarlyBeanPostProcessor.class, EARLY_INFRASTRUCTURE_BEAN_NAME, constructorArgs ->
- constructorArgs.addIndexedArgumentValue(0, registrarReference));
-
- // Main processor
- addInfrastructureBeanDefinition(
- registry, BeanOverrideBeanFactoryPostProcessor.class, INFRASTRUCTURE_BEAN_NAME, constructorArgs ->
- constructorArgs.addIndexedArgumentValue(0, registrarReference));
- }
-
- private static void addInfrastructureBeanDefinition(BeanDefinitionRegistry registry,
- Class> clazz, String beanName, Consumer Processors are generally linked to one or more specific concrete
- * annotations (meta-annotated with {@link BeanOverride @BeanOverride}) and
- * concrete {@link OverrideMetadata} implementations.
+ * At least one composed annotations meta-annotated with
+ * {@link BeanOverride @BeanOverride}) is a companion of this processor and
+ * may provide additional user settings that drive how the concrete
+ * {@link OverrideMetadata} is configured.
*
* Implementations are required to have a no-argument constructor and be
* stateless.
*
* @author Simon Baslé
+ * @author Stephane Nicoll
* @since 6.2
*/
@FunctionalInterface
@@ -38,12 +40,12 @@ public interface BeanOverrideProcessor {
/**
* Create an {@link OverrideMetadata} instance for the given annotated field.
- * @param overrideAnnotation the field annotation
- * @param testClass the test class being processed, which can be different
- * from the {@code field.getDeclaringClass()} in case the field is inherited
- * from a superclass
+ * @param overrideAnnotation the composed annotation that defines the
+ * {@link BeanOverride @BeanOverride} that triggers this processor
+ * @param testClass the test class being processed
* @param field the annotated field
- * @return a new {@link OverrideMetadata} instance
+ * @return the {@link OverrideMetadata} instance that should handle the
+ * given field
*/
OverrideMetadata createMetadata(Annotation overrideAnnotation, Class> testClass, Field field);
}
diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideRegistrar.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideRegistrar.java
index eb98ffe27a3..6c4e2cf8acc 100644
--- a/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideRegistrar.java
+++ b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideRegistrar.java
@@ -18,7 +18,6 @@ package org.springframework.test.context.bean.override;
import java.lang.reflect.Field;
import java.util.HashMap;
-import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@@ -26,11 +25,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
-import org.springframework.beans.factory.config.ConstructorArgumentValues;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
@@ -46,49 +41,49 @@ import org.springframework.util.StringUtils;
*/
class BeanOverrideRegistrar implements BeanFactoryAware {
- static final String INFRASTRUCTURE_BEAN_NAME = BeanOverrideRegistrar.class.getName();
-
private final Map The resulting complete set of test classes will be parsed as soon as
- * the {@link BeanOverrideRegistrar} is constructed.
- * @param registry the bean definition registry
- * @param detectedTestClasses a partial {@link Set} of {@link Class classes}
- * that are expected to contain bean overriding annotations
- */
- public static void register(BeanDefinitionRegistry registry, @Nullable Set Requires that the original bean definition exists.
+ * Fails if the original bean definition exists. To create a new bean
+ * definition in such a case, use {@link #REPLACE_OR_CREATE_DEFINITION}.
*/
REPLACE_DEFINITION,
/**
- * Replace a given bean definition, immediately preparing a singleton instance.
- * If the original bean definition does not exist, an override definition
- * will be created instead of failing.
+ * Replace or create a given bean definition, immediately preparing a
+ * singleton instance.
+ * Contrary to {@link #REPLACE_DEFINITION} this create a new bean
+ * definition if the target bean definition does not exist rather than
+ * failing.
*/
REPLACE_OR_CREATE_DEFINITION,
/**
* Intercept and process an early bean reference rather than a bean
- * definition, allowing variants of bean overriding to wrap the instance
- * (e.g. to delegate to actual methods in the context of a mocking "spy").
+ * definition, allowing variants of bean overriding to wrap the instance.
+ * For instance, to delegate to actual methods in the context of a mocking "spy".
*/
WRAP_BEAN
diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideTestExecutionListener.java
index 44b28a08e3c..18c53f2338d 100644
--- a/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideTestExecutionListener.java
+++ b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideTestExecutionListener.java
@@ -20,17 +20,15 @@ import java.lang.reflect.Field;
import java.util.function.BiConsumer;
import org.springframework.test.context.TestContext;
+import org.springframework.test.context.TestExecutionListener;
import org.springframework.test.context.support.AbstractTestExecutionListener;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.util.ReflectionUtils;
/**
- * {@code TestExecutionListener} that enables Bean Override support in tests,
- * injecting overridden beans in appropriate fields of the test instance.
- *
- * Some Bean Override implementations might additionally require the use of
- * additional listeners, which should be mentioned in the javadoc for the
- * corresponding annotations.
+ * {@link TestExecutionListener} implementation that enables Bean Override
+ * support in tests, injecting overridden beans in appropriate fields of the
+ * test instance.
*
* @author Simon Baslé
* @since 6.2
@@ -56,9 +54,9 @@ public class BeanOverrideTestExecutionListener extends AbstractTestExecutionList
}
/**
- * Using a registered {@link BeanOverrideBeanFactoryPostProcessor}, find metadata
- * associated with the current test class and ensure fields are injected
- * with the overridden bean instance.
+ * Process the test instance and make sure that flagged fields for bean
+ * overriding are processed. Each field get is value updated with the
+ * overridden bean instance.
*/
protected void injectFields(TestContext testContext) {
postProcessFields(testContext, (testMetadata, overrideRegistrar) -> overrideRegistrar.inject(
@@ -66,9 +64,9 @@ public class BeanOverrideTestExecutionListener extends AbstractTestExecutionList
}
/**
- * Using a registered {@link BeanOverrideBeanFactoryPostProcessor}, find metadata
- * associated with the current test class and ensure fields are nulled out
- * and then re-injected with the overridden bean instance.
+ * Process the test instance and make sure that flagged fields for bean
+ * overriding are processed. If a fresh instance is required, the field
+ * is nulled out and then re-injected with the overridden bean instance.
* This method does nothing if the
* {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE}
* attribute is not present in the {@code TestContext}.
diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/convention/TestBeanOverrideProcessor.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/convention/TestBeanOverrideProcessor.java
index a02f879ec68..b8b156ba282 100644
--- a/spring-test/src/main/java/org/springframework/test/context/bean/override/convention/TestBeanOverrideProcessor.java
+++ b/spring-test/src/main/java/org/springframework/test/context/bean/override/convention/TestBeanOverrideProcessor.java
@@ -69,7 +69,7 @@ class TestBeanOverrideProcessor implements BeanOverrideProcessor {
* @param methodNames a set of supported names for the factory method
* @return the corresponding factory method
* @throws IllegalStateException if a matching factory method cannot
- * be found or multiple methods have a match
+ * be found or multiple methods match
*/
static Method findTestBeanFactoryMethod(Class> clazz, Class> methodReturnType, String... methodNames) {
Assert.isTrue(methodNames.length > 0, "At least one candidate method name is required");
diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoBeanMetadata.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoBeanMetadata.java
index 8465889ba19..b1f99958002 100644
--- a/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoBeanMetadata.java
+++ b/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoBeanMetadata.java
@@ -151,7 +151,8 @@ class MockitoBeanMetadata extends MockitoMetadata {
if (this.serializable) {
settings.serializable();
}
- return (T) mock(getBeanType().resolve(), settings);
+ Class> targetType = getBeanType().resolve();
+ return (T) mock(targetType, settings);
}
}
diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideProcessor.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideProcessor.java
index 83a2a6c3cb3..12dc919b51e 100644
--- a/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideProcessor.java
+++ b/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideProcessor.java
@@ -23,11 +23,13 @@ import org.springframework.core.ResolvableType;
import org.springframework.test.context.bean.override.BeanOverrideProcessor;
/**
- * A {@link BeanOverrideProcessor} for mockito-related annotations
- * ({@link MockitoBean} and {@link MockitoSpyBean}).
+ * {@link BeanOverrideProcessor} implementation for Mockito support. Both mocking
+ * and spying are supported.
*
* @author Simon Baslé
* @since 6.2
+ * @see MockitoBean
+ * @see MockitoSpyBean
*/
class MockitoBeanOverrideProcessor implements BeanOverrideProcessor {
diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoMetadata.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoMetadata.java
index 26311b6433f..e92d1cd219f 100644
--- a/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoMetadata.java
+++ b/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoMetadata.java
@@ -29,7 +29,7 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
- * Base class for {@link MockitoBeanMetadata} and {@link MockitoSpyBeanMetadata}.
+ * Base class for Mockito override metadata.
*
* @author Phillip Webb
* @since 6.2
@@ -94,7 +94,7 @@ abstract class MockitoMetadata extends OverrideMetadata {
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(@Nullable Object obj) {
if (obj == this) {
return true;
}
diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanMetadata.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanMetadata.java
index 78454cd8090..1a8b27e7f5c 100644
--- a/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanMetadata.java
+++ b/spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanMetadata.java
@@ -31,6 +31,7 @@ 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.test.util.AopTestUtils;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -39,9 +40,10 @@ import org.springframework.util.StringUtils;
import static org.mockito.Mockito.mock;
/**
- * A complete definition that can be used to create a Mockito spy.
+ * {@link OverrideMetadata} for Mockito {@code spy} support.
*
* @author Phillip Webb
+ * @author Simon Baslé
* @since 6.2
*/
class MockitoSpyBeanMetadata extends MockitoMetadata {
@@ -52,7 +54,6 @@ class MockitoSpyBeanMetadata extends MockitoMetadata {
}
MockitoSpyBeanMetadata(String name, MockReset reset, boolean proxyTargetAware, Field field, ResolvableType typeToSpy) {
-
super(name, reset, proxyTargetAware, field, typeToSpy, BeanOverrideStrategy.WRAP_BEAN);
Assert.notNull(typeToSpy, "typeToSpy must not be null");
}
diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideBeanFactoryPostProcessorTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideBeanFactoryPostProcessorTests.java
index 8754cc95d5b..79713a42de2 100644
--- a/spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideBeanFactoryPostProcessorTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideBeanFactoryPostProcessorTests.java
@@ -177,8 +177,7 @@ class BeanOverrideBeanFactoryPostProcessorTests {
private AnnotationConfigApplicationContext createContext(Class>... classes) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
- BeanOverrideRegistrar.register(context, Set.of(classes));
- BeanOverrideBeanFactoryPostProcessor.register(context);
+ BeanOverrideContextCustomizer.registerInfrastructure(context, Set.of(classes));
return context;
}
@@ -193,6 +192,7 @@ class BeanOverrideBeanFactoryPostProcessorTests {
*/
static final SomeInterface OVERRIDE = new SomeImplementation();
+
static final ExampleService OVERRIDE_SERVICE = new FailingExampleService();
static class ReplaceBeans {