diff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-mockitobean.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-mockitobean.adoc index 2056f6454f..6aa5ddd9c2 100644 --- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-mockitobean.adoc +++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-mockitobean.adoc @@ -1,9 +1,10 @@ [[spring-testing-annotation-beanoverriding-mockitobean]] = `@MockitoBean` and `@MockitoSpyBean` -`@MockitoBean` and `@MockitoSpyBean` are used on fields in test classes to override beans -in the test's `ApplicationContext` with a Mockito _mock_ or _spy_, respectively. In the -latter case, an early instance of the original bean is captured and wrapped by the spy. +`@MockitoBean` and `@MockitoSpyBean` are used on non-static fields in test classes to +override beans in the test's `ApplicationContext` with a Mockito _mock_ or _spy_, +respectively. In the latter case, an early instance of the original bean is captured and +wrapped by the spy. By default, the annotated field's type is used to search for candidate beans to override. If multiple candidates match, `@Qualifier` can be provided to narrow the candidate to diff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testbean.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testbean.adoc index 6da8abed74..f814e50c00 100644 --- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testbean.adoc +++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-spring/annotation-testbean.adoc @@ -1,8 +1,8 @@ [[spring-testing-annotation-beanoverriding-testbean]] = `@TestBean` -`@TestBean` is used on a field in a test class to override a specific bean in the test's -`ApplicationContext` with an instance provided by a factory method. +`@TestBean` is used on a non-static field in a test class to override a specific bean in +the test's `ApplicationContext` with an instance provided by a factory method. The associated factory method name is derived from the annotated field's name, or the bean name if specified. The factory method must be `static`, accept no arguments, and diff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/bean-overriding.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/bean-overriding.adoc index b35ee1dd3a..52edc4a599 100644 --- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/bean-overriding.adoc +++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/bean-overriding.adoc @@ -2,7 +2,8 @@ = Bean Overriding in Tests Bean overriding in tests refers to the ability to override specific beans in the -`ApplicationContext` for a test class, by annotating one or more fields in the test class. +`ApplicationContext` for a test class, by annotating one or more non-static fields in the +test class. NOTE: This feature is intended as a less risky alternative to the practice of registering a bean via `@Bean` with the `DefaultListableBeanFactory` @@ -41,9 +42,10 @@ The `spring-test` module registers implementations of the latter two {spring-framework-code}/spring-test/src/main/resources/META-INF/spring.factories[`META-INF/spring.factories` properties file]. -The bean overriding infrastructure searches in test classes for any field meta-annotated -with `@BeanOverride` and instantiates the corresponding `BeanOverrideProcessor` which is -responsible for creating an appropriate `BeanOverrideHandler`. +The bean overriding infrastructure searches in test classes for any non-static field that +is meta-annotated with `@BeanOverride` and instantiates the corresponding +`BeanOverrideProcessor` which is responsible for creating an appropriate +`BeanOverrideHandler`. The internal `BeanOverrideBeanFactoryPostProcessor` then uses bean override handlers to alter the test's `ApplicationContext` by creating, replacing, or wrapping beans as 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 8aaceb8529..910eb50195 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 @@ -30,7 +30,7 @@ import org.springframework.aot.hint.annotation.Reflective; *
Specifying this annotation registers the configured {@link BeanOverrideProcessor} * which must be capable of handling the composed annotation and its attributes. * - *
Since the composed annotation should only be applied to fields, it is + *
Since the composed annotation should only be applied to non-static fields, it is * expected that it is meta-annotated with {@link Target @Target(ElementType.FIELD)}. * *
For concrete examples, see
diff --git a/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideHandler.java b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideHandler.java
index 79bcdaea7f..b0f6c0f56d 100644
--- a/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideHandler.java
+++ b/spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideHandler.java
@@ -18,6 +18,7 @@ package org.springframework.test.context.bean.override;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
@@ -105,6 +106,8 @@ public abstract class BeanOverrideHandler {
private static void processField(Field field, Class> testClass, List By default, the bean to spy is inferred from the type of the annotated
* field. If multiple candidates exist, a {@code @Qualifier} annotation can be
diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideHandlerTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideHandlerTests.java
index 85b4d0df2f..1a64107989 100644
--- a/spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideHandlerTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideHandlerTests.java
@@ -86,6 +86,14 @@ class BeanOverrideHandlerTests {
.withMessageContaining(faultyField.toString());
}
+ @Test // gh-33922
+ void forTestClassWithStaticBeanOverrideField() {
+ Field staticField = field(StaticBeanOverrideField.class, "message");
+ assertThatIllegalStateException()
+ .isThrownBy(() -> BeanOverrideHandler.forTestClass(StaticBeanOverrideField.class))
+ .withMessage("@BeanOverride field must not be static: " + staticField);
+ }
+
@Test
void getBeanNameIsNullByDefault() {
BeanOverrideHandler handler = createBeanOverrideHandler(field(ConfigA.class, "noQualifier"));
@@ -246,6 +254,12 @@ class BeanOverrideHandlerTests {
}
}
+ static class StaticBeanOverrideField {
+
+ @DummyBean
+ static String message;
+ }
+
static class ConfigA {
ExampleService noQualifier;