Browse Source

Polish Bean Override internals and tests

pull/34398/head
Sam Brannen 11 months ago
parent
commit
ff9b7678a7
  1. 2
      spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideHandler.java
  2. 5
      spring-test/src/main/java/org/springframework/test/context/bean/override/BeanOverrideRegistry.java
  3. 2
      spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockBeans.java
  4. 4
      spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideBeanFactoryPostProcessorTests.java
  5. 12
      spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideHandlerTests.java
  6. 33
      spring-test/src/test/java/org/springframework/test/context/bean/override/BeanOverrideTestUtils.java
  7. 13
      spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanOverrideHandlerTests.java
  8. 52
      spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideHandlerTests.java
  9. 40
      spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideProcessorTests.java
  10. 11
      spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanOverrideHandlerTests.java

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

@ -243,6 +243,8 @@ public abstract class BeanOverrideHandler { @@ -243,6 +243,8 @@ public abstract class BeanOverrideHandler {
!Objects.equals(this.strategy, that.strategy)) {
return false;
}
// by-name lookup
if (this.beanName != null) {
return true;
}

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -109,8 +109,7 @@ class BeanOverrideRegistry { @@ -109,8 +109,7 @@ class BeanOverrideRegistry {
void inject(Object target, BeanOverrideHandler handler) {
String beanName = this.handlerToBeanNameMap.get(handler);
Assert.state(StringUtils.hasLength(beanName),
() -> "No bean found for BeanOverrideHandler: " + handler);
Assert.state(StringUtils.hasLength(beanName), () -> "No bean found for BeanOverrideHandler: " + handler);
inject(handler.getField(), target, beanName);
}

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -395,7 +395,7 @@ class BeanOverrideBeanFactoryPostProcessorTests { @@ -395,7 +395,7 @@ class BeanOverrideBeanFactoryPostProcessorTests {
private static AnnotationConfigApplicationContext createContext(Class<?> testClass) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
Set<BeanOverrideHandler> handlers = new LinkedHashSet<>(BeanOverrideHandler.forTestClass(testClass));
Set<BeanOverrideHandler> handlers = new LinkedHashSet<>(BeanOverrideTestUtils.findHandlers(testClass));
new BeanOverrideContextCustomizer(handlers).customizeContext(context, mock(MergedContextConfiguration.class));
return context;
}

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -51,14 +51,14 @@ class BeanOverrideHandlerTests { @@ -51,14 +51,14 @@ class BeanOverrideHandlerTests {
@Test
void forTestClassWithSingleField() {
List<BeanOverrideHandler> handlers = BeanOverrideHandler.forTestClass(SingleAnnotation.class);
List<BeanOverrideHandler> handlers = BeanOverrideTestUtils.findHandlers(SingleAnnotation.class);
assertThat(handlers).singleElement().satisfies(hasBeanOverrideHandler(
field(SingleAnnotation.class, "message"), String.class, null));
}
@Test
void forTestClassWithMultipleFields() {
List<BeanOverrideHandler> handlers = BeanOverrideHandler.forTestClass(MultipleAnnotations.class);
List<BeanOverrideHandler> handlers = BeanOverrideTestUtils.findHandlers(MultipleAnnotations.class);
assertThat(handlers).hasSize(2)
.anySatisfy(hasBeanOverrideHandler(
field(MultipleAnnotations.class, "message"), String.class, null))
@ -68,7 +68,7 @@ class BeanOverrideHandlerTests { @@ -68,7 +68,7 @@ class BeanOverrideHandlerTests {
@Test
void forTestClassWithMultipleFieldsWithIdenticalMetadata() {
List<BeanOverrideHandler> handlers = BeanOverrideHandler.forTestClass(MultipleAnnotationsDuplicate.class);
List<BeanOverrideHandler> handlers = BeanOverrideTestUtils.findHandlers(MultipleAnnotationsDuplicate.class);
assertThat(handlers).hasSize(2)
.anySatisfy(hasBeanOverrideHandler(
field(MultipleAnnotationsDuplicate.class, "message1"), String.class, "messageBean"))
@ -81,7 +81,7 @@ class BeanOverrideHandlerTests { @@ -81,7 +81,7 @@ class BeanOverrideHandlerTests {
void forTestClassWithCompetingBeanOverrideAnnotationsOnSameField() {
Field faultyField = field(MultipleAnnotationsOnSameField.class, "message");
assertThatIllegalStateException()
.isThrownBy(() -> BeanOverrideHandler.forTestClass(MultipleAnnotationsOnSameField.class))
.isThrownBy(() -> BeanOverrideTestUtils.findHandlers(MultipleAnnotationsOnSameField.class))
.withMessageStartingWith("Multiple @BeanOverride annotations found")
.withMessageContaining(faultyField.toString());
}
@ -90,7 +90,7 @@ class BeanOverrideHandlerTests { @@ -90,7 +90,7 @@ class BeanOverrideHandlerTests {
void forTestClassWithStaticBeanOverrideField() {
Field staticField = field(StaticBeanOverrideField.class, "message");
assertThatIllegalStateException()
.isThrownBy(() -> BeanOverrideHandler.forTestClass(StaticBeanOverrideField.class))
.isThrownBy(() -> BeanOverrideTestUtils.findHandlers(StaticBeanOverrideField.class))
.withMessage("@BeanOverride field must not be static: " + staticField);
}

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

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
/*
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.context.bean.override;
import java.util.List;
/**
* Test utilities for Bean Overrides.
*
* @author Sam Brannen
* @since 6.2.2
*/
public abstract class BeanOverrideTestUtils {
public static List<BeanOverrideHandler> findHandlers(Class<?> testClass) {
return BeanOverrideHandler.forTestClass(testClass);
}
}

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,6 +26,7 @@ import org.springframework.beans.factory.annotation.Qualifier; @@ -26,6 +26,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.ResolvableType;
import org.springframework.test.context.bean.override.BeanOverrideHandler;
import org.springframework.test.context.bean.override.BeanOverrideStrategy;
import org.springframework.test.context.bean.override.BeanOverrideTestUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
@ -42,21 +43,21 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException; @@ -42,21 +43,21 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
class TestBeanOverrideHandlerTests {
@Test
void setsBeanNameToNullIfAnnotationNameIsNull() {
List<BeanOverrideHandler> handlers = BeanOverrideHandler.forTestClass(SampleOneOverride.class);
void beanNameIsSetToNullIfAnnotationNameIsEmpty() {
List<BeanOverrideHandler> handlers = BeanOverrideTestUtils.findHandlers(SampleOneOverride.class);
assertThat(handlers).singleElement().extracting(BeanOverrideHandler::getBeanName).isNull();
}
@Test
void setsBeanNameToAnnotationName() {
List<BeanOverrideHandler> handlers = BeanOverrideHandler.forTestClass(SampleOneOverrideWithName.class);
void beanNameIsSetToAnnotationName() {
List<BeanOverrideHandler> handlers = BeanOverrideTestUtils.findHandlers(SampleOneOverrideWithName.class);
assertThat(handlers).singleElement().extracting(BeanOverrideHandler::getBeanName).isEqualTo("anotherBean");
}
@Test
void failsWithMissingMethod() {
assertThatIllegalStateException()
.isThrownBy(() -> BeanOverrideHandler.forTestClass(SampleMissingMethod.class))
.isThrownBy(() -> BeanOverrideTestUtils.findHandlers(SampleMissingMethod.class))
.withMessage("No static method found named message() in %s with return type %s",
SampleMissingMethod.class.getName(), String.class.getName());
}

52
spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideHandlerTests.java

@ -26,6 +26,7 @@ import org.mockito.Answers; @@ -26,6 +26,7 @@ import org.mockito.Answers;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.test.context.bean.override.BeanOverrideHandler;
import org.springframework.test.context.bean.override.BeanOverrideTestUtils;
import org.springframework.util.ReflectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
@ -34,87 +35,89 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -34,87 +35,89 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link MockitoBeanOverrideHandler}.
*
* @author Stephane Nicoll
* @author Sam Brannen
* @since 6.2
*/
class MockitoBeanOverrideHandlerTests {
@Test
void forTestClassSetsNameToNullIfAnnotationNameIsNull() {
List<BeanOverrideHandler> list = BeanOverrideHandler.forTestClass(SampleOneMock.class);
void beanNameIsSetToNullIfAnnotationNameIsEmpty() {
List<BeanOverrideHandler> list = BeanOverrideTestUtils.findHandlers(SampleOneMock.class);
assertThat(list).singleElement().satisfies(handler -> assertThat(handler.getBeanName()).isNull());
}
@Test
void forTestClassSetsNameToAnnotationName() {
List<BeanOverrideHandler> list = BeanOverrideHandler.forTestClass(SampleOneMockWithName.class);
void beanNameIsSetToAnnotationName() {
List<BeanOverrideHandler> list = BeanOverrideTestUtils.findHandlers(SampleOneMockWithName.class);
assertThat(list).singleElement().satisfies(handler -> assertThat(handler.getBeanName()).isEqualTo("anotherService"));
}
@Test
void isEqualToWithSameInstance() {
MockitoBeanOverrideHandler handler = createBeanOverrideHandler(sampleField("service"));
void isEqualToWithSameInstanceFromField() {
MockitoBeanOverrideHandler handler = createHandler(sampleField("service"));
assertThat(handler).isEqualTo(handler);
assertThat(handler).hasSameHashCodeAs(handler);
}
@Test
void isEqualToWithSameMetadata() {
MockitoBeanOverrideHandler handler1 = createBeanOverrideHandler(sampleField("service"));
MockitoBeanOverrideHandler handler2 = createBeanOverrideHandler(sampleField("service"));
void isEqualToWithSameMetadataFromField() {
MockitoBeanOverrideHandler handler1 = createHandler(sampleField("service"));
MockitoBeanOverrideHandler handler2 = createHandler(sampleField("service"));
assertThat(handler1).isEqualTo(handler2);
assertThat(handler1).hasSameHashCodeAs(handler2);
}
@Test
void isNotEqualEqualToByTypeLookupWithSameMetadataButDifferentField() {
MockitoBeanOverrideHandler handler1 = createBeanOverrideHandler(sampleField("service"));
MockitoBeanOverrideHandler handler2 = createBeanOverrideHandler(sampleField("service2"));
MockitoBeanOverrideHandler handler1 = createHandler(sampleField("service"));
MockitoBeanOverrideHandler handler2 = createHandler(sampleField("service2"));
assertThat(handler1).isNotEqualTo(handler2);
}
@Test
void isEqualEqualToByNameLookupWithSameMetadataButDifferentField() {
MockitoBeanOverrideHandler handler1 = createBeanOverrideHandler(sampleField("service3"));
MockitoBeanOverrideHandler handler2 = createBeanOverrideHandler(sampleField("service4"));
MockitoBeanOverrideHandler handler1 = createHandler(sampleField("service3"));
MockitoBeanOverrideHandler handler2 = createHandler(sampleField("service4"));
assertThat(handler1).isEqualTo(handler2);
assertThat(handler1).hasSameHashCodeAs(handler2);
}
@Test
void isNotEqualToWithSameMetadataButDifferentBeanName() {
MockitoBeanOverrideHandler handler1 = createBeanOverrideHandler(sampleField("service"));
MockitoBeanOverrideHandler handler2 = createBeanOverrideHandler(sampleField("service3"));
MockitoBeanOverrideHandler handler1 = createHandler(sampleField("service"));
MockitoBeanOverrideHandler handler2 = createHandler(sampleField("service3"));
assertThat(handler1).isNotEqualTo(handler2);
}
@Test
void isNotEqualToWithSameMetadataButDifferentExtraInterfaces() {
MockitoBeanOverrideHandler handler1 = createBeanOverrideHandler(sampleField("service"));
MockitoBeanOverrideHandler handler2 = createBeanOverrideHandler(sampleField("service5"));
MockitoBeanOverrideHandler handler1 = createHandler(sampleField("service"));
MockitoBeanOverrideHandler handler2 = createHandler(sampleField("service5"));
assertThat(handler1).isNotEqualTo(handler2);
}
@Test
void isNotEqualToWithSameMetadataButDifferentAnswers() {
MockitoBeanOverrideHandler handler1 = createBeanOverrideHandler(sampleField("service"));
MockitoBeanOverrideHandler handler2 = createBeanOverrideHandler(sampleField("service6"));
MockitoBeanOverrideHandler handler1 = createHandler(sampleField("service"));
MockitoBeanOverrideHandler handler2 = createHandler(sampleField("service6"));
assertThat(handler1).isNotEqualTo(handler2);
}
@Test
void isNotEqualToWithSameMetadataButDifferentSerializableFlag() {
MockitoBeanOverrideHandler handler1 = createBeanOverrideHandler(sampleField("service"));
MockitoBeanOverrideHandler handler2 = createBeanOverrideHandler(sampleField("service7"));
MockitoBeanOverrideHandler handler1 = createHandler(sampleField("service"));
MockitoBeanOverrideHandler handler2 = createHandler(sampleField("service7"));
assertThat(handler1).isNotEqualTo(handler2);
}
private Field sampleField(String fieldName) {
private static Field sampleField(String fieldName) {
Field field = ReflectionUtils.findField(Sample.class, fieldName);
assertThat(field).isNotNull();
return field;
}
private MockitoBeanOverrideHandler createBeanOverrideHandler(Field field) {
private static MockitoBeanOverrideHandler createHandler(Field field) {
MockitoBean annotation = AnnotatedElementUtils.getMergedAnnotation(field, MockitoBean.class);
return new MockitoBeanOverrideHandler(field, ResolvableType.forClass(field.getType()), annotation);
}
@ -124,14 +127,12 @@ class MockitoBeanOverrideHandlerTests { @@ -124,14 +127,12 @@ class MockitoBeanOverrideHandlerTests {
@MockitoBean
String service;
}
static class SampleOneMockWithName {
@MockitoBean("anotherService")
String service;
}
static class Sample {
@ -156,7 +157,6 @@ class MockitoBeanOverrideHandlerTests { @@ -156,7 +157,6 @@ class MockitoBeanOverrideHandlerTests {
@MockitoBean(serializable = true)
private String service7;
}
}

40
spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideProcessorTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,56 +24,60 @@ import org.junit.jupiter.api.Test; @@ -24,56 +24,60 @@ import org.junit.jupiter.api.Test;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.Nullable;
import org.springframework.test.context.bean.override.BeanOverrideHandler;
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.assertThatIllegalStateException;
/**
* Tests for {@link MockitoBeanOverrideProcessorTests}
* Tests for {@link MockitoBeanOverrideProcessor}.
*
* @author Simon Baslé
* @author Sam Brannen
* @since 6.2
*/
public class MockitoBeanOverrideProcessorTests {
class MockitoBeanOverrideProcessorTests {
private final MockitoBeanOverrideProcessor processor = new MockitoBeanOverrideProcessor();
private final Field field = ReflectionUtils.findField(TestCase.class, "number");
@Test
void mockAnnotationCreatesMockitoBeanOverrideHandler() throws NoSuchFieldException {
void mockAnnotationCreatesMockitoBeanOverrideHandler() {
MockitoBean annotation = AnnotationUtils.synthesizeAnnotation(MockitoBean.class);
Class<?> clazz = MockitoConf.class;
Field field = clazz.getField("a");
BeanOverrideHandler object = this.processor.createHandler(annotation, clazz, field);
BeanOverrideHandler object = processor.createHandler(annotation, TestCase.class, field);
assertThat(object).isExactlyInstanceOf(MockitoBeanOverrideHandler.class);
}
@Test
void spyAnnotationCreatesMockitoSpyBeanOverrideHandler() throws NoSuchFieldException {
void spyAnnotationCreatesMockitoSpyBeanOverrideHandler() {
MockitoSpyBean annotation = AnnotationUtils.synthesizeAnnotation(MockitoSpyBean.class);
Class<?> clazz = MockitoConf.class;
Field field = clazz.getField("a");
BeanOverrideHandler object = this.processor.createHandler(annotation, clazz, field);
BeanOverrideHandler object = processor.createHandler(annotation, TestCase.class, field);
assertThat(object).isExactlyInstanceOf(MockitoSpyBeanOverrideHandler.class);
}
@Test
void otherAnnotationThrows() throws NoSuchFieldException {
Class<?> clazz = MockitoConf.class;
Field field = clazz.getField("a");
void otherAnnotationThrows() {
Annotation annotation = field.getAnnotation(Nullable.class);
assertThatIllegalStateException()
.isThrownBy(() -> this.processor.createHandler(annotation, clazz, field))
.isThrownBy(() -> processor.createHandler(annotation, TestCase.class, field))
.withMessage("Invalid annotation passed to MockitoBeanOverrideProcessor: expected either " +
"@MockitoBean or @MockitoSpyBean on field %s.%s", field.getDeclaringClass().getName(),
field.getName());
}
static class MockitoConf {
static class TestCase {
@Nullable
@MockitoBean
@MockitoSpyBean
public ExampleService a;
Integer number;
}
}

11
spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanOverrideHandlerTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,6 +24,7 @@ import org.junit.jupiter.api.Test; @@ -24,6 +24,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.test.context.bean.override.BeanOverrideHandler;
import org.springframework.test.context.bean.override.BeanOverrideTestUtils;
import org.springframework.util.ReflectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
@ -36,14 +37,14 @@ import static org.assertj.core.api.Assertions.assertThat; @@ -36,14 +37,14 @@ import static org.assertj.core.api.Assertions.assertThat;
class MockitoSpyBeanOverrideHandlerTests {
@Test
void forTestClassSetsNameToNullIfAnnotationNameIsNull() {
List<BeanOverrideHandler> list = BeanOverrideHandler.forTestClass(SampleOneSpy.class);
void beanNameIsSetToNullIfAnnotationNameIsEmpty() {
List<BeanOverrideHandler> list = BeanOverrideTestUtils.findHandlers(SampleOneSpy.class);
assertThat(list).singleElement().satisfies(handler -> assertThat(handler.getBeanName()).isNull());
}
@Test
void forTestClassSetsNameToAnnotationName() {
List<BeanOverrideHandler> list = BeanOverrideHandler.forTestClass(SampleOneSpyWithName.class);
void beanNameIsSetToAnnotationName() {
List<BeanOverrideHandler> list = BeanOverrideTestUtils.findHandlers(SampleOneSpyWithName.class);
assertThat(list).singleElement().satisfies(handler -> assertThat(handler.getBeanName()).isEqualTo("anotherService"));
}

Loading…
Cancel
Save