Browse Source

Merge branch '6.2.x'

pull/34193/head
Sam Brannen 1 year ago
parent
commit
087641c508
  1. 3
      spring-core/src/main/java/org/springframework/util/ReflectionUtils.java
  2. 45
      spring-core/src/test/java/org/springframework/util/PropertyPlaceholderHelperTests.java
  3. 18
      spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/AbstractMockitoBeanOverrideHandler.java
  4. 2
      spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockBeans.java
  5. 4
      spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideHandler.java
  6. 4
      spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoBeanOverrideProcessor.java
  7. 2
      spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoResetTestExecutionListener.java
  8. 12
      spring-test/src/main/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanOverrideHandler.java
  9. 2
      spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanTests.java

3
spring-core/src/main/java/org/springframework/util/ReflectionUtils.java

@ -710,8 +710,7 @@ public abstract class ReflectionUtils {
// Keep backing up the inheritance hierarchy. // Keep backing up the inheritance hierarchy.
Class<?> targetClass = clazz; Class<?> targetClass = clazz;
do { do {
Field[] fields = getDeclaredFields(targetClass); for (Field field : getDeclaredFields(targetClass)) {
for (Field field : fields) {
if (ff != null && !ff.matches(field)) { if (ff != null && !ff.matches(field)) {
continue; continue;
} }

45
spring-core/src/test/java/org/springframework/util/PropertyPlaceholderHelperTests.java

@ -17,13 +17,11 @@
package org.springframework.util; package org.springframework.util;
import java.util.Properties; import java.util.Properties;
import java.util.stream.Stream;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver; import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
@ -44,6 +42,7 @@ class PropertyPlaceholderHelperTests {
private final PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}"); private final PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
@Test @Test
void withProperties() { void withProperties() {
String text = "foo=${foo}"; String text = "foo=${foo}";
@ -116,8 +115,8 @@ class PropertyPlaceholderHelperTests {
props.setProperty("foo", "bar"); props.setProperty("foo", "bar");
PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}", null, null, false); PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}", null, null, false);
assertThatExceptionOfType(PlaceholderResolutionException.class).isThrownBy(() -> assertThatExceptionOfType(PlaceholderResolutionException.class)
helper.replacePlaceholders(text, props)); .isThrownBy(() -> helper.replacePlaceholders(text, props));
} }
@Nested @Nested
@ -126,7 +125,14 @@ class PropertyPlaceholderHelperTests {
private final PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}", ":", null, true); private final PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}", ":", null, true);
@ParameterizedTest(name = "{0} -> {1}") @ParameterizedTest(name = "{0} -> {1}")
@MethodSource("defaultValues") @CsvSource(delimiterString = "->", textBlock = """
${invalid:test} -> test
${invalid:${one}} -> 1
${invalid:${one}${two}} -> 12
${invalid:${one}:${two}} -> 1:2
${invalid:${also_invalid:test}} -> test
${invalid:${also_invalid:${one}}} -> 1
""")
void defaultValueIsApplied(String text, String value) { void defaultValueIsApplied(String text, String value) {
Properties properties = new Properties(); Properties properties = new Properties();
properties.setProperty("one", "1"); properties.setProperty("one", "1");
@ -142,24 +148,26 @@ class PropertyPlaceholderHelperTests {
verify(resolver, never()).resolvePlaceholder("two"); verify(resolver, never()).resolvePlaceholder("two");
} }
static Stream<Arguments> defaultValues() { @ParameterizedTest(name = "{0} -> {1}")
return Stream.of( @CsvSource(delimiterString = "->", textBlock = """
Arguments.of("${invalid:test}", "test"), ${prefix://my-service} -> example-service
Arguments.of("${invalid:${one}}", "1"), ${p1} -> example-service
Arguments.of("${invalid:${one}${two}}", "12"), """)
Arguments.of("${invalid:${one}:${two}}", "1:2"), void placeholdersWithExactMatchAreConsidered(String text, String expected) {
Arguments.of("${invalid:${also_invalid:test}}", "test"), Properties properties = new Properties();
Arguments.of("${invalid:${also_invalid:${one}}}", "1") properties.setProperty("prefix://my-service", "example-service");
); properties.setProperty("px", "prefix");
properties.setProperty("p1", "${prefix://my-service}");
assertThat(this.helper.replacePlaceholders(text, properties)).isEqualTo(expected);
} }
} }
PlaceholderResolver mockPlaceholderResolver(String... pairs) {
private static PlaceholderResolver mockPlaceholderResolver(String... pairs) {
if (pairs.length % 2 == 1) { if (pairs.length % 2 == 1) {
throw new IllegalArgumentException("size must be even, it is a set of key=value pairs"); throw new IllegalArgumentException("size must be even, it is a set of key=value pairs");
} }
PlaceholderResolver resolver = mock(PlaceholderResolver.class); PlaceholderResolver resolver = mock();
for (int i = 0; i < pairs.length; i += 2) { for (int i = 0; i < pairs.length; i += 2) {
String key = pairs[i]; String key = pairs[i];
String value = pairs[i + 1]; String value = pairs[i + 1];
@ -168,5 +176,4 @@ class PropertyPlaceholderHelperTests {
return resolver; return resolver;
} }
} }

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

@ -57,20 +57,20 @@ abstract class AbstractMockitoBeanOverrideHandler extends BeanOverrideHandler {
@Override @Override
protected void trackOverrideInstance(Object mock, SingletonBeanRegistry trackingBeanRegistry) { protected void trackOverrideInstance(Object mock, SingletonBeanRegistry trackingBeanRegistry) {
getMockitoBeans(trackingBeanRegistry).add(mock); getMockBeans(trackingBeanRegistry).add(mock);
} }
private static MockitoBeans getMockitoBeans(SingletonBeanRegistry trackingBeanRegistry) { private static MockBeans getMockBeans(SingletonBeanRegistry trackingBeanRegistry) {
String beanName = MockitoBeans.class.getName(); String beanName = MockBeans.class.getName();
MockitoBeans mockitoBeans = null; MockBeans mockBeans = null;
if (trackingBeanRegistry.containsSingleton(beanName)) { if (trackingBeanRegistry.containsSingleton(beanName)) {
mockitoBeans = (MockitoBeans) trackingBeanRegistry.getSingleton(beanName); mockBeans = (MockBeans) trackingBeanRegistry.getSingleton(beanName);
} }
if (mockitoBeans == null) { if (mockBeans == null) {
mockitoBeans = new MockitoBeans(); mockBeans = new MockBeans();
trackingBeanRegistry.registerSingleton(beanName, mockitoBeans); trackingBeanRegistry.registerSingleton(beanName, mockBeans);
} }
return mockitoBeans; return mockBeans;
} }
@Override @Override

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

@ -28,7 +28,7 @@ import org.mockito.Mockito;
* @author Sam Brannen * @author Sam Brannen
* @since 6.2 * @since 6.2
*/ */
class MockitoBeans { class MockBeans {
private final List<Object> beans = new ArrayList<>(); private final List<Object> beans = new ArrayList<>();

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

@ -64,13 +64,13 @@ class MockitoBeanOverrideHandler extends AbstractMockitoBeanOverrideHandler {
} }
private MockitoBeanOverrideHandler(Field field, ResolvableType typeToMock, @Nullable String beanName, private MockitoBeanOverrideHandler(Field field, ResolvableType typeToMock, @Nullable String beanName,
BeanOverrideStrategy strategy, MockReset reset, Class<?>[] extraInterfaces, @Nullable Answers answers, BeanOverrideStrategy strategy, MockReset reset, Class<?>[] extraInterfaces, Answers answers,
boolean serializable) { boolean serializable) {
super(field, typeToMock, beanName, strategy, reset); super(field, typeToMock, beanName, strategy, reset);
Assert.notNull(typeToMock, "'typeToMock' must not be null"); Assert.notNull(typeToMock, "'typeToMock' must not be null");
this.extraInterfaces = asClassSet(extraInterfaces); this.extraInterfaces = asClassSet(extraInterfaces);
this.answers = (answers != null ? answers : Answers.RETURNS_DEFAULTS); this.answers = answers;
this.serializable = serializable; this.serializable = serializable;
} }

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

@ -35,8 +35,8 @@ class MockitoBeanOverrideProcessor implements BeanOverrideProcessor {
@Override @Override
public AbstractMockitoBeanOverrideHandler createHandler(Annotation overrideAnnotation, Class<?> testClass, Field field) { public AbstractMockitoBeanOverrideHandler createHandler(Annotation overrideAnnotation, Class<?> testClass, Field field) {
if (overrideAnnotation instanceof MockitoBean mockBean) { if (overrideAnnotation instanceof MockitoBean mockitoBean) {
return new MockitoBeanOverrideHandler(field, ResolvableType.forField(field, testClass), mockBean); return new MockitoBeanOverrideHandler(field, ResolvableType.forField(field, testClass), mockitoBean);
} }
else if (overrideAnnotation instanceof MockitoSpyBean spyBean) { else if (overrideAnnotation instanceof MockitoSpyBean spyBean) {
return new MockitoSpyBeanOverrideHandler(field, ResolvableType.forField(field, testClass), spyBean); return new MockitoSpyBeanOverrideHandler(field, ResolvableType.forField(field, testClass), spyBean);

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

@ -115,7 +115,7 @@ public class MockitoResetTestExecutionListener extends AbstractTestExecutionList
} }
} }
try { try {
beanFactory.getBean(MockitoBeans.class).resetAll(reset); beanFactory.getBean(MockBeans.class).resetAll(reset);
} }
catch (NoSuchBeanDefinitionException ex) { catch (NoSuchBeanDefinitionException ex) {
// Continue // Continue

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

@ -48,15 +48,9 @@ class MockitoSpyBeanOverrideHandler extends AbstractMockitoBeanOverrideHandler {
new SpringAopBypassingVerificationStartedListener(); new SpringAopBypassingVerificationStartedListener();
MockitoSpyBeanOverrideHandler(Field field, ResolvableType typeToSpy, MockitoSpyBean spyAnnotation) { MockitoSpyBeanOverrideHandler(Field field, ResolvableType typeToSpy, MockitoSpyBean spyBean) {
this(field, typeToSpy, (StringUtils.hasText(spyAnnotation.name()) ? spyAnnotation.name() : null), super(field, typeToSpy, (StringUtils.hasText(spyBean.name()) ? spyBean.name() : null),
spyAnnotation.reset()); BeanOverrideStrategy.WRAP, spyBean.reset());
}
MockitoSpyBeanOverrideHandler(Field field, ResolvableType typeToSpy, @Nullable String beanName,
MockReset reset) {
super(field, typeToSpy, beanName, BeanOverrideStrategy.WRAP, reset);
Assert.notNull(typeToSpy, "typeToSpy must not be null"); Assert.notNull(typeToSpy, "typeToSpy must not be null");
} }

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

@ -113,7 +113,7 @@ public class TestBeanTests {
} }
@Test @Test
void contextCustomizerCannotBeCreatedWitCompetingOverrideMethods() { void contextCustomizerCannotBeCreatedWithCompetingOverrideMethods() {
GenericApplicationContext context = new GenericApplicationContext(); GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("bean", String.class, () -> "example"); context.registerBean("bean", String.class, () -> "example");
assertThatIllegalStateException() assertThatIllegalStateException()

Loading…
Cancel
Save