Skip to content

Commit 02517e5

Browse files
committed
Polish
This commit reviews the structure of several classes to comply with our guidelines. Also, rather than exposing a static method to configure the context in a test, we call the high-level API directly.
1 parent 0165529 commit 02517e5

File tree

7 files changed

+94
-97
lines changed

7 files changed

+94
-97
lines changed

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,6 @@ public BeanOverrideBeanFactoryPostProcessor(BeanOverrideRegistrar overrideRegist
7777
}
7878

7979

80-
@Override
81-
public int getOrder() {
82-
return Ordered.LOWEST_PRECEDENCE - 10;
83-
}
84-
85-
8680
@Override
8781
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
8882
if (!(beanFactory instanceof BeanDefinitionRegistry registry)) {
@@ -92,6 +86,11 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
9286
postProcessWithRegistry(beanFactory, registry);
9387
}
9488

89+
@Override
90+
public int getOrder() {
91+
return Ordered.LOWEST_PRECEDENCE - 10;
92+
}
93+
9594
private void postProcessWithRegistry(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry) {
9695
for (OverrideMetadata metadata : this.overrideRegistrar.getOverrideMetadata()) {
9796
registerBeanOverride(beanFactory, registry, metadata);
@@ -240,15 +239,15 @@ private Set<String> getExistingBeanNamesByType(ConfigurableListableBeanFactory b
240239
}
241240

242241

243-
static final class WrapEarlyBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
242+
static class WrapEarlyBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
244243
PriorityOrdered {
245244

246245
private final Map<String, Object> earlyReferences = new ConcurrentHashMap<>(16);
247246

248247
private final BeanOverrideRegistrar overrideRegistrar;
249248

250249

251-
private WrapEarlyBeanPostProcessor(BeanOverrideRegistrar registrar) {
250+
WrapEarlyBeanPostProcessor(BeanOverrideRegistrar registrar) {
252251
this.overrideRegistrar = registrar;
253252
}
254253

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

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,16 @@ class BeanOverrideContextCustomizer implements ContextCustomizer {
5555
this.detectedClasses = detectedClasses;
5656
}
5757

58-
static void registerInfrastructure(BeanDefinitionRegistry registry, Set<Class<?>> detectedClasses) {
58+
@Override
59+
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
60+
if (!(context instanceof BeanDefinitionRegistry registry)) {
61+
throw new IllegalStateException("Cannot process bean overrides with an ApplicationContext " +
62+
"that doesn't implement BeanDefinitionRegistry: " + context.getClass());
63+
}
64+
registerInfrastructure(registry, this.detectedClasses);
65+
}
66+
67+
private void registerInfrastructure(BeanDefinitionRegistry registry, Set<Class<?>> detectedClasses) {
5968
addInfrastructureBeanDefinition(registry, BeanOverrideRegistrar.class, REGISTRAR_BEAN_NAME,
6069
constructorArgs -> constructorArgs.addIndexedArgumentValue(0, detectedClasses));
6170
RuntimeBeanReference registrarReference = new RuntimeBeanReference(REGISTRAR_BEAN_NAME);
@@ -67,7 +76,7 @@ static void registerInfrastructure(BeanDefinitionRegistry registry, Set<Class<?>
6776
constructorArgs -> constructorArgs.addIndexedArgumentValue(0, registrarReference));
6877
}
6978

70-
private static void addInfrastructureBeanDefinition(BeanDefinitionRegistry registry,
79+
private void addInfrastructureBeanDefinition(BeanDefinitionRegistry registry,
7180
Class<?> clazz, String beanName, Consumer<ConstructorArgumentValues> constructorArgumentsConsumer) {
7281

7382
if (!registry.containsBeanDefinition(beanName)) {
@@ -80,24 +89,15 @@ private static void addInfrastructureBeanDefinition(BeanDefinitionRegistry regis
8089
}
8190

8291
@Override
83-
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
84-
if (!(context instanceof BeanDefinitionRegistry registry)) {
85-
throw new IllegalStateException("Cannot process bean overrides with an ApplicationContext " +
86-
"that doesn't implement BeanDefinitionRegistry: " + context.getClass());
87-
}
88-
registerInfrastructure(registry, this.detectedClasses);
89-
}
90-
91-
@Override
92-
public boolean equals(Object obj) {
93-
if (obj == this) {
92+
public boolean equals(Object other) {
93+
if (other == this) {
9494
return true;
9595
}
96-
if (obj == null || obj.getClass() != getClass()) {
96+
if (other == null || other.getClass() != getClass()) {
9797
return false;
9898
}
99-
BeanOverrideContextCustomizer other = (BeanOverrideContextCustomizer) obj;
100-
return this.detectedClasses.equals(other.detectedClasses);
99+
BeanOverrideContextCustomizer that = (BeanOverrideContextCustomizer) other;
100+
return this.detectedClasses.equals(that.detectedClasses);
101101
}
102102

103103
@Override

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

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,39 @@
4545
*/
4646
class TestBeanOverrideProcessor implements BeanOverrideProcessor {
4747

48+
@Override
49+
public TestBeanOverrideMetadata createMetadata(Annotation overrideAnnotation, Class<?> testClass, Field field) {
50+
if (!(overrideAnnotation instanceof TestBean testBeanAnnotation)) {
51+
throw new IllegalStateException("Invalid annotation passed to %s: expected @TestBean on field %s.%s"
52+
.formatted(getClass().getSimpleName(), field.getDeclaringClass().getName(), field.getName()));
53+
}
54+
Method overrideMethod;
55+
String methodName = testBeanAnnotation.methodName();
56+
if (!methodName.isBlank()) {
57+
// If the user specified an explicit method name, search for that.
58+
overrideMethod = findTestBeanFactoryMethod(testClass, field.getType(), methodName);
59+
}
60+
else {
61+
// Otherwise, search for candidate factory methods using the convention
62+
// suffix and the field name or explicit bean name (if any).
63+
List<String> candidateMethodNames = new ArrayList<>();
64+
candidateMethodNames.add(field.getName() + TestBean.CONVENTION_SUFFIX);
65+
66+
String beanName = testBeanAnnotation.name();
67+
if (StringUtils.hasText(beanName)) {
68+
candidateMethodNames.add(beanName + TestBean.CONVENTION_SUFFIX);
69+
}
70+
overrideMethod = findTestBeanFactoryMethod(testClass, field.getType(), candidateMethodNames);
71+
}
72+
String beanName = (StringUtils.hasText(testBeanAnnotation.name()) ? testBeanAnnotation.name() : null);
73+
return new TestBeanOverrideMetadata(field, ResolvableType.forField(field, testClass), beanName, overrideMethod);
74+
}
75+
4876
/**
4977
* Find a test bean factory {@link Method} for the given {@link Class}.
5078
* <p>Delegates to {@link #findTestBeanFactoryMethod(Class, Class, List)}.
5179
*/
52-
static Method findTestBeanFactoryMethod(Class<?> clazz, Class<?> methodReturnType, String... methodNames) {
80+
Method findTestBeanFactoryMethod(Class<?> clazz, Class<?> methodReturnType, String... methodNames) {
5381
return findTestBeanFactoryMethod(clazz, methodReturnType, List.of(methodNames));
5482
}
5583

@@ -76,7 +104,7 @@ static Method findTestBeanFactoryMethod(Class<?> clazz, Class<?> methodReturnTyp
76104
* @throws IllegalStateException if a matching factory method cannot
77105
* be found or multiple methods match
78106
*/
79-
static Method findTestBeanFactoryMethod(Class<?> clazz, Class<?> methodReturnType, List<String> methodNames) {
107+
Method findTestBeanFactoryMethod(Class<?> clazz, Class<?> methodReturnType, List<String> methodNames) {
80108
Assert.notEmpty(methodNames, "At least one candidate method name is required");
81109
Set<String> supportedNames = new LinkedHashSet<>(methodNames);
82110
MethodFilter methodFilter = method -> (Modifier.isStatic(method.getModifiers()) &&
@@ -88,47 +116,17 @@ static Method findTestBeanFactoryMethod(Class<?> clazz, Class<?> methodReturnTyp
88116
Assert.state(!methods.isEmpty(), () -> """
89117
Failed to find a static test bean factory method in %s with return type %s \
90118
whose name matches one of the supported candidates %s""".formatted(
91-
clazz.getName(), methodReturnType.getName(), supportedNames));
119+
clazz.getName(), methodReturnType.getName(), supportedNames));
92120

93121
long uniqueMethodNameCount = methods.stream().map(Method::getName).distinct().count();
94122
Assert.state(uniqueMethodNameCount == 1, () -> """
95123
Found %d competing static test bean factory methods in %s with return type %s \
96124
whose name matches one of the supported candidates %s""".formatted(
97-
uniqueMethodNameCount, clazz.getName(), methodReturnType.getName(), supportedNames));
125+
uniqueMethodNameCount, clazz.getName(), methodReturnType.getName(), supportedNames));
98126

99127
return methods.iterator().next();
100128
}
101129

102-
@Override
103-
public TestBeanOverrideMetadata createMetadata(Annotation overrideAnnotation, Class<?> testClass, Field field) {
104-
if (!(overrideAnnotation instanceof TestBean testBeanAnnotation)) {
105-
throw new IllegalStateException("Invalid annotation passed to %s: expected @TestBean on field %s.%s"
106-
.formatted(getClass().getSimpleName(), field.getDeclaringClass().getName(), field.getName()));
107-
}
108-
Method overrideMethod;
109-
String methodName = testBeanAnnotation.methodName();
110-
if (!methodName.isBlank()) {
111-
// If the user specified an explicit method name, search for that.
112-
overrideMethod = findTestBeanFactoryMethod(testClass, field.getType(), methodName);
113-
}
114-
else {
115-
// Otherwise, search for candidate factory methods using the convention
116-
// suffix and the field name or explicit bean name (if any).
117-
List<String> candidateMethodNames = new ArrayList<>();
118-
candidateMethodNames.add(field.getName() + TestBean.CONVENTION_SUFFIX);
119-
120-
String beanName = testBeanAnnotation.name();
121-
if (StringUtils.hasText(beanName)) {
122-
candidateMethodNames.add(beanName + TestBean.CONVENTION_SUFFIX);
123-
}
124-
overrideMethod = findTestBeanFactoryMethod(testClass, field.getType(), candidateMethodNames);
125-
}
126-
127-
String beanName = (StringUtils.hasText(testBeanAnnotation.name()) ? testBeanAnnotation.name() : null);
128-
return new TestBeanOverrideMetadata(field, ResolvableType.forField(field, testClass), beanName, overrideMethod);
129-
}
130-
131-
132130
private static Set<Method> findMethods(Class<?> clazz, MethodFilter methodFilter) {
133131
Set<Method> methods = MethodIntrospector.selectMethods(clazz, methodFilter);
134132
if (methods.isEmpty() && TestContextAnnotationUtils.searchEnclosingClass(clazz)) {

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

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ class MockitoBeanOverrideMetadata extends MockitoOverrideMetadata {
6969
this.serializable = serializable;
7070
}
7171

72+
private static Set<Class<?>> asClassSet(@Nullable Class<?>[] classes) {
73+
Set<Class<?>> classSet = new LinkedHashSet<>();
74+
if (classes != null) {
75+
classSet.addAll(Arrays.asList(classes));
76+
}
77+
return Collections.unmodifiableSet(classSet);
78+
}
79+
7280

7381
/**
7482
* Return the extra interfaces.
@@ -99,12 +107,21 @@ protected Object createOverride(String beanName, @Nullable BeanDefinition existi
99107
return createMock(beanName);
100108
}
101109

102-
private Set<Class<?>> asClassSet(@Nullable Class<?>[] classes) {
103-
Set<Class<?>> classSet = new LinkedHashSet<>();
104-
if (classes != null) {
105-
classSet.addAll(Arrays.asList(classes));
110+
@SuppressWarnings("unchecked")
111+
<T> T createMock(String name) {
112+
MockSettings settings = MockReset.withSettings(getReset());
113+
if (StringUtils.hasLength(name)) {
114+
settings.name(name);
106115
}
107-
return Collections.unmodifiableSet(classSet);
116+
if (!this.extraInterfaces.isEmpty()) {
117+
settings.extraInterfaces(ClassUtils.toClassArray(this.extraInterfaces));
118+
}
119+
settings.defaultAnswer(this.answer);
120+
if (this.serializable) {
121+
settings.serializable();
122+
}
123+
Class<?> targetType = getBeanType().resolve();
124+
return (T) mock(targetType, settings);
108125
}
109126

110127
@Override
@@ -140,21 +157,4 @@ public String toString() {
140157
.toString();
141158
}
142159

143-
@SuppressWarnings("unchecked")
144-
<T> T createMock(String name) {
145-
MockSettings settings = MockReset.withSettings(getReset());
146-
if (StringUtils.hasLength(name)) {
147-
settings.name(name);
148-
}
149-
if (!this.extraInterfaces.isEmpty()) {
150-
settings.extraInterfaces(ClassUtils.toClassArray(this.extraInterfaces));
151-
}
152-
settings.defaultAnswer(this.answer);
153-
if (this.serializable) {
154-
settings.serializable();
155-
}
156-
Class<?> targetType = getBeanType().resolve();
157-
return (T) mock(targetType, settings);
158-
}
159-
160160
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.springframework.context.support.SimpleThreadScope;
3838
import org.springframework.core.Ordered;
3939
import org.springframework.core.ResolvableType;
40+
import org.springframework.test.context.MergedContextConfiguration;
4041
import org.springframework.test.context.bean.override.example.ExampleBeanOverrideAnnotation;
4142
import org.springframework.test.context.bean.override.example.ExampleService;
4243
import org.springframework.test.context.bean.override.example.FailingExampleService;
@@ -47,6 +48,7 @@
4748
import static org.assertj.core.api.Assertions.assertThat;
4849
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
4950
import static org.assertj.core.api.Assertions.assertThatNoException;
51+
import static org.mockito.Mockito.mock;
5052

5153
/**
5254
* Tests for {@link BeanOverrideBeanFactoryPostProcessor} combined with a
@@ -199,9 +201,9 @@ private void isTheValueField(RootBeanDefinition def) {
199201
});
200202
}
201203

202-
private AnnotationConfigApplicationContext createContext(Class<?>... classes) {
204+
private AnnotationConfigApplicationContext createContext(Class<?> testClass) {
203205
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
204-
BeanOverrideContextCustomizer.registerInfrastructure(context, Set.of(classes));
206+
new BeanOverrideContextCustomizer(Set.of(testClass)).customizeContext(context, mock(MergedContextConfiguration.class));
205207
return context;
206208
}
207209

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*/
2525
interface TestBeanFactory {
2626

27-
public static String createTestMessage() {
27+
static String createTestMessage() {
2828
return "test";
2929
}
3030

0 commit comments

Comments
 (0)