Skip to content

Commit cf3171d

Browse files
committed
Find unique @⁠TestBean factory methods in class hierarchy
I accidentally introduced a regression in commit d185bb1 by no longer checking the number of unique method names found when searching for @⁠TestBean factory methods. This commit reintroduces that check and introduces a proper unit test in TestBeanOverrideProcessorTests. It turns out that we already had an integration test that was intended to check for this scenario; however, that test actually did not test this scenario due to a copy-and-paste error. Thus, this commit also updates TestBeanInheritanceIntegrationTests so that fieldInSupertypeWithPrioritizedFactoryMethodInSubtype() tests what it's supposed to.
1 parent 069c678 commit cf3171d

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,16 @@ static Method findTestBeanFactoryMethod(Class<?> clazz, Class<?> methodReturnTyp
9292

9393
Set<Method> methods = findMethods(clazz, methodFilter);
9494

95-
int methodCount = methods.size();
96-
Assert.state(methodCount > 0, () -> """
95+
Assert.state(!methods.isEmpty(), () -> """
9796
Failed to find a static test bean factory method in %s with return type %s \
9897
whose name matches one of the supported candidates %s""".formatted(
9998
clazz.getName(), methodReturnType.getName(), supportedNames));
10099

101-
Assert.state(methodCount == 1, () -> """
100+
long uniqueMethodNameCount = methods.stream().map(Method::getName).distinct().count();
101+
Assert.state(uniqueMethodNameCount == 1, () -> """
102102
Found %d competing static test bean factory methods in %s with return type %s \
103103
whose name matches one of the supported candidates %s""".formatted(
104-
methodCount, clazz.getName(), methodReturnType.getName(), supportedNames));
104+
uniqueMethodNameCount, clazz.getName(), methodReturnType.getName(), supportedNames));
105105

106106
return methods.iterator().next();
107107
}

spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanInheritanceIntegrationTests.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ static Pojo someBeanTestOverride() {
6161
return new FakePojo("someBeanOverride");
6262
}
6363

64+
// Hides otherBeanTestOverride() defined in AbstractTestBeanIntegrationTestCase.
65+
static Pojo otherBeanTestOverride() {
66+
return new FakePojo("otherBean in subclass");
67+
}
68+
6469
@Test
6570
void fieldInSubtypeWithFactoryMethodInSupertype() {
6671
assertThat(ctx.getBean("pojo")).as("applicationContext").hasToString("in superclass");
@@ -75,8 +80,8 @@ void fieldInSupertypeWithFactoryMethodInSubtype() {
7580

7681
@Test
7782
void fieldInSupertypeWithPrioritizedFactoryMethodInSubtype() {
78-
assertThat(ctx.getBean("someBean")).as("applicationContext").hasToString("someBeanOverride");
79-
assertThat(this.someBean.getValue()).as("injection point").isEqualTo("someBeanOverride");
83+
assertThat(ctx.getBean("otherBean")).as("applicationContext").hasToString("otherBean in subclass");
84+
assertThat(super.otherBean.getValue()).as("injection point").isEqualTo("otherBean in subclass");
8085
}
8186

8287
@Test

spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanOverrideProcessorTests.java

+29
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.springframework.lang.NonNull;
2727
import org.springframework.test.context.bean.override.convention.TestBeanOverrideProcessor.TestBeanOverrideMetadata;
2828
import org.springframework.test.context.bean.override.example.ExampleService;
29+
import org.springframework.util.ReflectionUtils;
2930

3031
import static org.assertj.core.api.Assertions.assertThat;
3132
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@@ -51,6 +52,16 @@ void findTestBeanFactoryMethodFindsFromCandidateNames() {
5152
assertThat(method.getName()).isEqualTo("example2");
5253
}
5354

55+
@Test
56+
void findTestBeanFactoryMethodFindsLocalMethodWhenSubclassMethodHidesSuperclassMethod() {
57+
Class<?> clazz = SubTestCase.class;
58+
Class<?> returnType = String.class;
59+
60+
Method method = findTestBeanFactoryMethod(clazz, returnType, "factory");
61+
62+
assertThat(method).isEqualTo(ReflectionUtils.findMethod(clazz, "factory"));
63+
}
64+
5465
@Test
5566
void findTestBeanFactoryMethodNotFound() {
5667
Class<?> clazz = MethodConventionTestCase.class;
@@ -174,4 +185,22 @@ static ExampleService explicit2() {
174185
}
175186
}
176187

188+
static class BaseTestCase {
189+
190+
@TestBean(methodName = "factory")
191+
public String field;
192+
193+
static String factory() {
194+
return null;
195+
}
196+
}
197+
198+
static class SubTestCase extends BaseTestCase {
199+
200+
// Hides factory() in superclass.
201+
static String factory() {
202+
return null;
203+
}
204+
}
205+
177206
}

0 commit comments

Comments
 (0)