18
18
19
19
import java .lang .reflect .Field ;
20
20
import java .util .List ;
21
- import java .util .function .BiConsumer ;
22
21
23
22
import org .springframework .test .context .TestContext ;
24
23
import org .springframework .test .context .support .AbstractTestExecutionListener ;
25
24
import org .springframework .test .context .support .DependencyInjectionTestExecutionListener ;
26
25
import org .springframework .util .ReflectionUtils ;
27
26
28
27
/**
29
- * {@code TestExecutionListener} that enables Bean Override support in tests,
30
- * injecting overridden beans in appropriate fields of the test instance.
28
+ * {@code TestExecutionListener} that enables {@link BeanOverride @BeanOverride}
29
+ * support in tests, by injecting overridden beans in appropriate fields of the
30
+ * test instance.
31
31
*
32
32
* @author Simon Baslé
33
+ * @author Sam Brannen
33
34
* @since 6.2
34
35
*/
35
36
public class BeanOverrideTestExecutionListener extends AbstractTestExecutionListener {
@@ -42,64 +43,57 @@ public int getOrder() {
42
43
return LOWEST_PRECEDENCE - 50 ;
43
44
}
44
45
45
- @ Override
46
- public void prepareTestInstance (TestContext testContext ) throws Exception {
47
- injectFields (testContext );
48
- }
49
-
50
- @ Override
51
- public void beforeTestMethod (TestContext testContext ) throws Exception {
52
- reinjectFieldsIfNecessary (testContext );
53
- }
54
-
55
46
/**
56
- * Process the test instance and make sure that fields flagged for bean
57
- * overriding are injected with the overridden bean instance.
47
+ * Inject each {@link BeanOverride @BeanOverride} field in the
48
+ * {@linkplain Object test instance} of the supplied {@linkplain TestContext
49
+ * test context} with a corresponding bean override instance.
58
50
*/
59
- protected void injectFields ( TestContext testContext ) {
60
- postProcessFields ( testContext , ( testMetadata , registrar ) ->
61
- registrar . inject ( testMetadata . testInstance , testMetadata . overrideMetadata ) );
51
+ @ Override
52
+ public void prepareTestInstance ( TestContext testContext ) throws Exception {
53
+ injectFields ( testContext , false );
62
54
}
63
55
64
56
/**
65
- * Process the test instance and make sure that fields flagged for bean
66
- * overriding are injected with the overridden bean instance, if necessary.
67
- * <p>If a fresh instance is required, the field is nulled out and then
68
- * re-injected with the overridden bean instance.
57
+ * Re-inject each {@link BeanOverride @BeanOverride} field in the
58
+ * {@linkplain Object test instance} of the supplied {@linkplain TestContext
59
+ * test context} with a corresponding bean override instance.
69
60
* <p>This method does nothing if the
70
- * {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE}
71
- * attribute is not present in the {@code TestContext} with a value of {@link Boolean#TRUE}.
61
+ * {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE
62
+ * REINJECT_DEPENDENCIES_ATTRIBUTE} attribute is not present in the
63
+ * {@code TestContext} with a value of {@link Boolean#TRUE}.
72
64
*/
73
- protected void reinjectFieldsIfNecessary (TestContext testContext ) throws Exception {
74
- if (Boolean .TRUE .equals (
75
- testContext .getAttribute (DependencyInjectionTestExecutionListener .REINJECT_DEPENDENCIES_ATTRIBUTE ))) {
76
-
77
- postProcessFields (testContext , (testMetadata , registrar ) -> {
78
- Object testInstance = testMetadata .testInstance ;
79
- Field field = testMetadata .overrideMetadata .getField ();
80
- ReflectionUtils .makeAccessible (field );
81
- ReflectionUtils .setField (field , testInstance , null );
82
- registrar .inject (testInstance , testMetadata .overrideMetadata );
83
- });
65
+ @ Override
66
+ public void beforeTestMethod (TestContext testContext ) throws Exception {
67
+ Object reinjectDependenciesAttribute = testContext .getAttribute (
68
+ DependencyInjectionTestExecutionListener .REINJECT_DEPENDENCIES_ATTRIBUTE );
69
+ if (Boolean .TRUE .equals (reinjectDependenciesAttribute )) {
70
+ injectFields (testContext , true );
84
71
}
85
72
}
86
73
87
- private void postProcessFields (TestContext testContext , BiConsumer <TestContextOverrideMetadata ,
88
- BeanOverrideRegistrar > consumer ) {
89
-
90
- Class <?> testClass = testContext .getTestClass ();
91
- Object testInstance = testContext .getTestInstance ();
92
-
93
- List <OverrideMetadata > metadataForFields = OverrideMetadata .forTestClass (testClass );
94
- if (!metadataForFields .isEmpty ()) {
74
+ /**
75
+ * Inject each {@link BeanOverride @BeanOverride} field in the test instance with
76
+ * a corresponding bean override instance.
77
+ * <p>If the {@code reinjectFields} flag is {@code true} (which indicates that
78
+ * a fresh instance is required), the field is nulled out before injecting
79
+ * the overridden bean instance.
80
+ */
81
+ private static void injectFields (TestContext testContext , boolean reinjectFields ) {
82
+ List <OverrideMetadata > overrideMetadataList = OverrideMetadata .forTestClass (testContext .getTestClass ());
83
+ if (!overrideMetadataList .isEmpty ()) {
84
+ Object testInstance = testContext .getTestInstance ();
95
85
BeanOverrideRegistrar registrar = testContext .getApplicationContext ()
96
86
.getBean (BeanOverrideContextCustomizer .REGISTRAR_BEAN_NAME , BeanOverrideRegistrar .class );
97
- for (OverrideMetadata metadata : metadataForFields ) {
98
- consumer .accept (new TestContextOverrideMetadata (testInstance , metadata ), registrar );
87
+
88
+ for (OverrideMetadata overrideMetadata : overrideMetadataList ) {
89
+ if (reinjectFields ) {
90
+ Field field = overrideMetadata .getField ();
91
+ ReflectionUtils .makeAccessible (field );
92
+ ReflectionUtils .setField (field , testInstance , null );
93
+ }
94
+ registrar .inject (testInstance , overrideMetadata );
99
95
}
100
96
}
101
97
}
102
98
103
- private record TestContextOverrideMetadata (Object testInstance , OverrideMetadata overrideMetadata ) {}
104
-
105
99
}
0 commit comments