Skip to content

Commit fd6b18a

Browse files
committed
Merge branch '6.2.x'
2 parents c5ec169 + ba70c13 commit fd6b18a

File tree

22 files changed

+1865
-48
lines changed

22 files changed

+1865
-48
lines changed

spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideTestExecutionListener.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,17 @@ public void beforeTestMethod(TestContext testContext) throws Exception {
9393
* a corresponding bean override instance.
9494
*/
9595
private static void injectFields(TestContext testContext) {
96-
List<BeanOverrideHandler> handlers = BeanOverrideHandler.forTestClass(testContext.getTestClass());
96+
Object testInstance = testContext.getTestInstance();
97+
// Since JUnit Jupiter 5.12, if the SpringExtension is used with Jupiter's
98+
// ExtensionContextScope.TEST_METHOD mode, the value returned from
99+
// testContext.getTestClass() may refer to the declaring class of the test
100+
// method which is about to be invoked (which may be in a @Nested class
101+
// within the class for the test instance). Thus, we use the class for the
102+
// test instance as the "test class".
103+
Class<?> testClass = testInstance.getClass();
104+
105+
List<BeanOverrideHandler> handlers = BeanOverrideHandler.forTestClass(testClass);
97106
if (!handlers.isEmpty()) {
98-
Object testInstance = testContext.getTestInstance();
99107
ApplicationContext applicationContext = testContext.getApplicationContext();
100108

101109
Assert.state(applicationContext.containsBean(BeanOverrideRegistry.BEAN_NAME), () -> """

spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -302,18 +302,19 @@ public void afterEach(ExtensionContext context) throws Exception {
302302
@Override
303303
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
304304
Parameter parameter = parameterContext.getParameter();
305+
Class<?> parameterType = parameter.getType();
305306
Executable executable = parameter.getDeclaringExecutable();
306307
PropertyProvider junitPropertyProvider = propertyName ->
307308
extensionContext.getConfigurationParameter(propertyName).orElse(null);
308309
return (TestConstructorUtils.isAutowirableConstructor(executable, junitPropertyProvider) ||
309-
ApplicationContext.class.isAssignableFrom(parameter.getType()) ||
310-
supportsApplicationEvents(parameterContext) ||
310+
ApplicationContext.class.isAssignableFrom(parameterType) ||
311+
supportsApplicationEvents(parameterType, executable) ||
311312
ParameterResolutionDelegate.isAutowirable(parameter, parameterContext.getIndex()));
312313
}
313314

314-
private boolean supportsApplicationEvents(ParameterContext parameterContext) {
315-
if (ApplicationEvents.class.isAssignableFrom(parameterContext.getParameter().getType())) {
316-
Assert.isTrue(parameterContext.getDeclaringExecutable() instanceof Method,
315+
private boolean supportsApplicationEvents(Class<?> parameterType, Executable executable) {
316+
if (ApplicationEvents.class.isAssignableFrom(parameterType)) {
317+
Assert.isTrue(executable instanceof Method,
317318
"ApplicationEvents can only be injected into test and lifecycle methods");
318319
return true;
319320
}
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.junit.jupiter.api.DisplayName;
2020
import org.junit.jupiter.api.Nested;
2121
import org.junit.jupiter.api.Test;
22+
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
2223

2324
import org.springframework.context.ApplicationContext;
2425
import org.springframework.context.ConfigurableApplicationContext;
@@ -30,14 +31,15 @@
3031
import static org.assertj.core.api.Assertions.assertThat;
3132

3233
/**
33-
* Integration tests for {@link TestBean} that use by-name lookup.
34+
* Integration tests for {@link TestBean} that use by-name lookup with test class
35+
* {@link ExtensionContextScope}.
3436
*
3537
* @author Simon Baslé
3638
* @author Sam Brannen
3739
* @since 6.2
3840
*/
3941
@SpringJUnitConfig
40-
public class TestBeanByNameLookupIntegrationTests {
42+
public class TestBeanByNameLookupTestClassScopedExtensionContextIntegrationTests {
4143

4244
@TestBean(name = "field")
4345
String field;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/*
2+
* Copyright 2002-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.test.context.bean.override.convention;
18+
19+
import org.junit.jupiter.api.DisplayName;
20+
import org.junit.jupiter.api.Nested;
21+
import org.junit.jupiter.api.Test;
22+
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
23+
import org.junit.platform.testkit.engine.EngineTestKit;
24+
25+
import org.springframework.context.ApplicationContext;
26+
import org.springframework.context.annotation.Bean;
27+
import org.springframework.context.annotation.Configuration;
28+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
29+
30+
import static org.assertj.core.api.Assertions.assertThat;
31+
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
32+
import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
33+
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
34+
35+
36+
/**
37+
* Integration tests for {@link TestBean} that use by-name lookup with
38+
* {@link ExtensionContextScope#TEST_METHOD}.
39+
*
40+
* @author Simon Baslé
41+
* @author Sam Brannen
42+
* @since 6.2.13
43+
*/
44+
public class TestBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests {
45+
46+
@Test
47+
void runTests() {
48+
EngineTestKit.engine("junit-jupiter")
49+
.configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
50+
.selectors(selectClass(TestCase.class))
51+
.execute()
52+
.testEvents()
53+
.assertStatistics(stats -> stats.started(12).succeeded(12).failed(0));
54+
}
55+
56+
57+
@SpringJUnitConfig
58+
public static class TestCase {
59+
60+
@TestBean(name = "field")
61+
String field;
62+
63+
@TestBean(name = "methodRenamed1", methodName = "field")
64+
String methodRenamed1;
65+
66+
static String field() {
67+
return "fieldOverride";
68+
}
69+
70+
static String nestedField() {
71+
return "nestedFieldOverride";
72+
}
73+
74+
@Test
75+
void fieldHasOverride(ApplicationContext ctx) {
76+
assertThat(ctx.getBean("field")).as("applicationContext").isEqualTo("fieldOverride");
77+
assertThat(field).as("injection point").isEqualTo("fieldOverride");
78+
}
79+
80+
@Test
81+
void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
82+
assertThat(ctx.getBean("methodRenamed1")).as("applicationContext").isEqualTo("fieldOverride");
83+
assertThat(methodRenamed1).as("injection point").isEqualTo("fieldOverride");
84+
}
85+
86+
87+
@Nested
88+
@DisplayName("With @TestBean in enclosing class and in @Nested class")
89+
public class TestBeanFieldInEnclosingClassTestCase {
90+
91+
@TestBean(name = "nestedField")
92+
String nestedField;
93+
94+
@TestBean(name = "methodRenamed2", methodName = "nestedField")
95+
String methodRenamed2;
96+
97+
98+
@Test
99+
void fieldHasOverride(ApplicationContext ctx) {
100+
assertThat(ctx.getBean("field")).as("applicationContext").isEqualTo("fieldOverride");
101+
assertThat(field).as("injection point").isEqualTo("fieldOverride");
102+
}
103+
104+
@Test
105+
void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
106+
assertThat(ctx.getBean("methodRenamed1")).as("applicationContext").isEqualTo("fieldOverride");
107+
assertThat(methodRenamed1).as("injection point").isEqualTo("fieldOverride");
108+
}
109+
110+
@Test
111+
void nestedFieldHasOverride(ApplicationContext ctx) {
112+
assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
113+
assertThat(nestedField).isEqualTo("nestedFieldOverride");
114+
}
115+
116+
@Test
117+
void nestedFieldWithMethodNameHasOverride(ApplicationContext ctx) {
118+
assertThat(ctx.getBean("methodRenamed2")).as("applicationContext").isEqualTo("nestedFieldOverride");
119+
assertThat(methodRenamed2).isEqualTo("nestedFieldOverride");
120+
}
121+
122+
@Nested
123+
@DisplayName("With @TestBean in the enclosing classes")
124+
public class TestBeanFieldInEnclosingClassLevel2TestCase {
125+
126+
@Test
127+
void fieldHasOverride(ApplicationContext ctx) {
128+
assertThat(ctx.getBean("field")).as("applicationContext").isEqualTo("fieldOverride");
129+
assertThat(field).as("injection point").isEqualTo("fieldOverride");
130+
}
131+
132+
@Test
133+
void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
134+
assertThat(ctx.getBean("methodRenamed1")).as("applicationContext").isEqualTo("fieldOverride");
135+
assertThat(methodRenamed1).as("injection point").isEqualTo("fieldOverride");
136+
}
137+
138+
@Test
139+
void nestedFieldHasOverride(ApplicationContext ctx) {
140+
assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
141+
assertThat(nestedField).isEqualTo("nestedFieldOverride");
142+
}
143+
144+
@Test
145+
void nestedFieldWithMethodNameHasOverride(ApplicationContext ctx) {
146+
assertThat(ctx.getBean("methodRenamed2")).as("applicationContext").isEqualTo("nestedFieldOverride");
147+
assertThat(methodRenamed2).isEqualTo("nestedFieldOverride");
148+
}
149+
}
150+
}
151+
152+
@Nested
153+
@DisplayName("With factory method in enclosing class")
154+
public class TestBeanFactoryMethodInEnclosingClassTestCase {
155+
156+
@TestBean(methodName = "nestedField", name = "nestedField")
157+
String nestedField;
158+
159+
@Test
160+
void nestedFieldHasOverride(ApplicationContext ctx) {
161+
assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
162+
assertThat(nestedField).isEqualTo("nestedFieldOverride");
163+
}
164+
165+
@Nested
166+
@DisplayName("With factory method in the enclosing class of the enclosing class")
167+
public class TestBeanFactoryMethodInEnclosingClassLevel2TestCase {
168+
169+
@TestBean(methodName = "nestedField", name = "nestedNestedField")
170+
String nestedNestedField;
171+
172+
@Test
173+
void nestedFieldHasOverride(ApplicationContext ctx) {
174+
assertThat(ctx.getBean("nestedNestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
175+
assertThat(nestedNestedField).isEqualTo("nestedFieldOverride");
176+
}
177+
}
178+
}
179+
}
180+
181+
@Configuration(proxyBeanMethods = false)
182+
static class Config {
183+
184+
@Bean("field")
185+
String bean1() {
186+
return "prod";
187+
}
188+
189+
@Bean("nestedField")
190+
String bean2() {
191+
return "nestedProd";
192+
}
193+
194+
@Bean("methodRenamed1")
195+
String bean3() {
196+
return "Prod";
197+
}
198+
199+
@Bean("methodRenamed2")
200+
String bean4() {
201+
return "NestedProd";
202+
}
203+
}
204+
205+
}
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.junit.jupiter.api.DisplayName;
2020
import org.junit.jupiter.api.Nested;
2121
import org.junit.jupiter.api.Test;
22+
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
2223

2324
import org.springframework.beans.factory.annotation.Autowired;
2425
import org.springframework.beans.factory.annotation.Qualifier;
@@ -35,14 +36,15 @@
3536
import static org.assertj.core.api.Assertions.assertThat;
3637

3738
/**
38-
* Integration tests for {@link MockitoBean} that use by-name lookup.
39+
* Integration tests for {@link MockitoBean} that use by-name lookup with test class
40+
* {@link ExtensionContextScope}.
3941
*
4042
* @author Simon Baslé
4143
* @author Sam Brannen
4244
* @since 6.2
4345
*/
4446
@SpringJUnitConfig
45-
public class MockitoBeanByNameLookupIntegrationTests {
47+
public class MockitoBeanByNameLookupTestClassScopedExtensionContextIntegrationTests {
4648

4749
@MockitoBean("field")
4850
ExampleService field;

0 commit comments

Comments
 (0)