Find unique @⁠TestBean factory methods in class hierarchy

I accidentally introduced a regression in commit d185bb1d97 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.
This commit is contained in:
Sam Brannen 2024-06-04 18:47:32 +02:00
parent 069c6788f5
commit cf3171dae0
3 changed files with 40 additions and 6 deletions

View File

@ -92,16 +92,16 @@ class TestBeanOverrideProcessor implements BeanOverrideProcessor {
Set<Method> methods = findMethods(clazz, methodFilter);
int methodCount = methods.size();
Assert.state(methodCount > 0, () -> """
Assert.state(!methods.isEmpty(), () -> """
Failed to find a static test bean factory method in %s with return type %s \
whose name matches one of the supported candidates %s""".formatted(
clazz.getName(), methodReturnType.getName(), supportedNames));
Assert.state(methodCount == 1, () -> """
long uniqueMethodNameCount = methods.stream().map(Method::getName).distinct().count();
Assert.state(uniqueMethodNameCount == 1, () -> """
Found %d competing static test bean factory methods in %s with return type %s \
whose name matches one of the supported candidates %s""".formatted(
methodCount, clazz.getName(), methodReturnType.getName(), supportedNames));
uniqueMethodNameCount, clazz.getName(), methodReturnType.getName(), supportedNames));
return methods.iterator().next();
}

View File

@ -61,6 +61,11 @@ public class TestBeanInheritanceIntegrationTests {
return new FakePojo("someBeanOverride");
}
// Hides otherBeanTestOverride() defined in AbstractTestBeanIntegrationTestCase.
static Pojo otherBeanTestOverride() {
return new FakePojo("otherBean in subclass");
}
@Test
void fieldInSubtypeWithFactoryMethodInSupertype() {
assertThat(ctx.getBean("pojo")).as("applicationContext").hasToString("in superclass");
@ -75,8 +80,8 @@ public class TestBeanInheritanceIntegrationTests {
@Test
void fieldInSupertypeWithPrioritizedFactoryMethodInSubtype() {
assertThat(ctx.getBean("someBean")).as("applicationContext").hasToString("someBeanOverride");
assertThat(this.someBean.getValue()).as("injection point").isEqualTo("someBeanOverride");
assertThat(ctx.getBean("otherBean")).as("applicationContext").hasToString("otherBean in subclass");
assertThat(super.otherBean.getValue()).as("injection point").isEqualTo("otherBean in subclass");
}
@Test

View File

@ -26,6 +26,7 @@ import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.NonNull;
import org.springframework.test.context.bean.override.convention.TestBeanOverrideProcessor.TestBeanOverrideMetadata;
import org.springframework.test.context.bean.override.example.ExampleService;
import org.springframework.util.ReflectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@ -51,6 +52,16 @@ class TestBeanOverrideProcessorTests {
assertThat(method.getName()).isEqualTo("example2");
}
@Test
void findTestBeanFactoryMethodFindsLocalMethodWhenSubclassMethodHidesSuperclassMethod() {
Class<?> clazz = SubTestCase.class;
Class<?> returnType = String.class;
Method method = findTestBeanFactoryMethod(clazz, returnType, "factory");
assertThat(method).isEqualTo(ReflectionUtils.findMethod(clazz, "factory"));
}
@Test
void findTestBeanFactoryMethodNotFound() {
Class<?> clazz = MethodConventionTestCase.class;
@ -174,4 +185,22 @@ class TestBeanOverrideProcessorTests {
}
}
static class BaseTestCase {
@TestBean(methodName = "factory")
public String field;
static String factory() {
return null;
}
}
static class SubTestCase extends BaseTestCase {
// Hides factory() in superclass.
static String factory() {
return null;
}
}
}