Merge branch '6.2.x'
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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<>();
|
||||||
|
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user