Harmonize component scan in slice tests
This commit updates ConfigurationPropertiesScanRegistrar to apply the same component scan filters than the ones applied on standard classpath scanning. As a result, configuration properties scanning is automatically disabled in slice tests and can be included by an explicit import or a dedicated TypeFilter implementation if necessary. Closes gh-16659
This commit is contained in:
parent
6d9a54a24f
commit
a3e94f4412
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2012-2019 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.boot.test.autoconfigure.web.client;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.bind.DefaultValue;
|
||||
|
||||
/**
|
||||
* Example {@link ConfigurationProperties} used to test the use of configuration
|
||||
* properties scan with sliced test.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@ConfigurationProperties("example")
|
||||
public class ExampleProperties {
|
||||
|
||||
private final String name;
|
||||
|
||||
public ExampleProperties(@DefaultValue("test") String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -53,6 +53,12 @@ class RestClientTestNoComponentIntegrationTests {
|
|||
.isThrownBy(() -> this.applicationContext.getBean(ExampleRestClient.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void examplePropertiesIsNotInjected() {
|
||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||
.isThrownBy(() -> this.applicationContext.getBean(ExampleProperties.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void manuallyCreateBean() {
|
||||
ExampleRestClient client = new ExampleRestClient(this.restTemplateBuilder);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2012-2019 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.boot.test.autoconfigure.web.client;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link RestClientTest @RestClientTest} with a {@link ConfigurationProperties}
|
||||
* annotated type.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@RestClientTest(components = ExampleProperties.class, properties = "example.name=Hello")
|
||||
class RestClientTestWithConfigurationPropertiesIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Test
|
||||
void configurationPropertiesCanBeAddedAsComponent() {
|
||||
assertThat(this.applicationContext.getBeansOfType(ExampleProperties.class).keySet())
|
||||
.containsOnly("example-org.springframework.boot.test.autoconfigure.web.client.ExampleProperties");
|
||||
assertThat(this.applicationContext.getBean(ExampleProperties.class).getName()).isEqualTo("Hello");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@ import java.util.Set;
|
|||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.boot.context.TypeExcludeFilter;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
|
|
@ -82,6 +83,9 @@ class ConfigurationPropertiesScanRegistrar
|
|||
scanner.setEnvironment(this.environment);
|
||||
scanner.setResourceLoader(this.resourceLoader);
|
||||
scanner.addIncludeFilter(new AnnotationTypeFilter(ConfigurationProperties.class));
|
||||
TypeExcludeFilter typeExcludeFilter = new TypeExcludeFilter();
|
||||
typeExcludeFilter.setBeanFactory(beanFactory);
|
||||
scanner.addExcludeFilter(typeExcludeFilter);
|
||||
for (String basePackage : packages) {
|
||||
if (StringUtils.hasText(basePackage)) {
|
||||
scan(beanFactory, registry, scanner, basePackage);
|
||||
|
|
|
|||
|
|
@ -87,10 +87,13 @@ class ConfigurationPropertiesScanRegistrarTests {
|
|||
.isFalse();
|
||||
BeanDefinition aDefinition = beanFactory.getBeanDefinition(
|
||||
"a-org.springframework.boot.context.properties.scan.valid.a.AScanConfiguration$AProperties");
|
||||
BeanDefinition bDefinition = beanFactory.getBeanDefinition(
|
||||
"b-org.springframework.boot.context.properties.scan.valid.b.BScanConfiguration$BProperties");
|
||||
BeanDefinition bFirstDefinition = beanFactory.getBeanDefinition(
|
||||
"b.first-org.springframework.boot.context.properties.scan.valid.b.BScanConfiguration$BFirstProperties");
|
||||
BeanDefinition bSecondDefinition = beanFactory.getBeanDefinition(
|
||||
"b.second-org.springframework.boot.context.properties.scan.valid.b.BScanConfiguration$BSecondProperties");
|
||||
assertThat(aDefinition).isExactlyInstanceOf(GenericBeanDefinition.class);
|
||||
assertThat(bDefinition).isExactlyInstanceOf(GenericBeanDefinition.class);
|
||||
assertThat(bFirstDefinition).isExactlyInstanceOf(GenericBeanDefinition.class);
|
||||
assertThat(bSecondDefinition).isExactlyInstanceOf(GenericBeanDefinition.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -16,14 +16,23 @@
|
|||
|
||||
package org.springframework.boot.context.properties;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.context.TypeExcludeFilter;
|
||||
import org.springframework.boot.context.properties.scan.valid.a.AScanConfiguration;
|
||||
import org.springframework.boot.context.properties.scan.valid.b.BScanConfiguration.BFirstProperties;
|
||||
import org.springframework.boot.context.properties.scan.valid.b.BScanConfiguration.BProperties;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.core.type.filter.AssignableTypeFilter;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
|
@ -89,6 +98,23 @@ class ConfigurationPropertiesScanTests {
|
|||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void scanImportBeanRegistrarShouldUsePackageName() {
|
||||
load(TestAnotherPackageConfiguration.class);
|
||||
assertThat(this.context.getBeanNamesForType(BProperties.class)).containsOnly(
|
||||
"b.first-org.springframework.boot.context.properties.scan.valid.b.BScanConfiguration$BFirstProperties",
|
||||
"b.second-org.springframework.boot.context.properties.scan.valid.b.BScanConfiguration$BSecondProperties");
|
||||
}
|
||||
|
||||
@Test
|
||||
void scanImportBeanRegistrarShouldApplyTypeExcludeFilter() {
|
||||
this.context.getBeanFactory().registerSingleton("filter", new ConfigurationPropertiesTestTypeExcludeFilter());
|
||||
this.context.register(TestAnotherPackageConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBeanNamesForType(BProperties.class)).containsOnly(
|
||||
"b.first-org.springframework.boot.context.properties.scan.valid.b.BScanConfiguration$BFirstProperties");
|
||||
}
|
||||
|
||||
private void load(Class<?>... classes) {
|
||||
this.context.register(classes);
|
||||
this.context.refresh();
|
||||
|
|
@ -99,4 +125,30 @@ class ConfigurationPropertiesScanTests {
|
|||
|
||||
}
|
||||
|
||||
@ConfigurationPropertiesScan(basePackages = "org.springframework.boot.context.properties.scan.valid.b")
|
||||
static class TestAnotherPackageConfiguration {
|
||||
|
||||
}
|
||||
|
||||
static class ConfigurationPropertiesTestTypeExcludeFilter extends TypeExcludeFilter {
|
||||
|
||||
@Override
|
||||
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
|
||||
throws IOException {
|
||||
AssignableTypeFilter typeFilter = new AssignableTypeFilter(BFirstProperties.class);
|
||||
return !typeFilter.match(metadataReader, metadataReaderFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return (this == o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(42);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,21 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
|||
|
||||
/**
|
||||
* @author Madhura Bhave
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class BScanConfiguration {
|
||||
|
||||
@ConfigurationProperties(prefix = "b")
|
||||
static class BProperties {
|
||||
public interface BProperties {
|
||||
|
||||
}
|
||||
|
||||
@ConfigurationProperties(prefix = "b.first")
|
||||
public static class BFirstProperties implements BProperties {
|
||||
|
||||
}
|
||||
|
||||
@ConfigurationProperties(prefix = "b.second")
|
||||
public static class BSecondProperties implements BProperties {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue