当我尝试从 .properties
文件与 .yaml
文件注入(inject) Map
时,我注意到 Spring 中的行为存在差异文件。我正在使用 Spring 的 ConfigurationProperties
来执行此操作。
文件:
products.yaml
:
test-service:
products:
1: alpha
2: bravo
3: charlie
产品.properties
:
test-service.products.1=alpha
test-service.products.2=bravo
test-service.products.3=charlie
我的 ProductProperties
类加载属性:
@ConfigurationProperties("test-service")
public class ProductProperties {
private final Map<String, String> products = new HashMap<>();
public Map<String, String> getProducts() {
return products;
}
}
单元测试ProductPropertiesPropertiesTest
,通过:
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ProductProperties.class)
@TestPropertySource("classpath:products.properties")
@EnableConfigurationProperties(ProductProperties.class)
public class ProductPropertiesPropertiesTest {
@Autowired
private ProductProperties productProperties;
@Test
public void testProperties() {
assertEquals(3, productProperties.getProducts().size()); // passes
}
}
单元测试 ProductPropertiesYamlTest
,失败:
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ProductProperties.class)
@TestPropertySource("classpath:products.yaml")
@EnableConfigurationProperties(ProductProperties.class)
public class ProductPropertiesYamlTest {
@Autowired
private ProductProperties productProperties;
@Test
public void testProperties() {
assertEquals(3, productProperties.getProducts().size()); // fails
}
}
两个测试之间的唯一区别在于属性的来源:.properties
文件(通过)和 .yaml
文件(失败)。
为什么?
最佳答案
您的代码中有两个问题
TestPropertySource无法使用 PropertySource
和 TestPropertySource
注释加载 YAML
文件
@TestPropertySource is a class-level annotation that is used to configure the locations() of properties files and inlined properties() to be added to the Environment's set of PropertySources for an ApplicationContext for integration tests.
YAML files cannot be loaded by using the @PropertySource annotation. So, in the case that you need to load values that way, you need to use a properties file.
因此,将您的 yml
文件名更改为 application.yml
,然后您仍然需要在测试类上添加 @SpringBootTest
注释来绑定(bind)这些yml 文件中的属性
Loading YAML Spring Boot有binder utils
To bind to properties like that by using Spring Boot’s Binder utilities (which is what @ConfigurationProperties does), you need to have a property in the target bean of type java.util.List (or Set) and you either need to provide a setter or initialize it with a mutable value.
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ProductProperties.class)
//default to application.yml
@EnableConfigurationProperties(ProductProperties.class)
@SpringBootTest
public class ProductPropertiesPropertiesTest {
@Autowired
private ProductProperties productProperties;
@Test
public void testProperties() {
assertEquals(3, productProperties.getProducts().size()); // passes
}
}
但是对于属性文件@SpringBootTest
是可选的,因为默认情况下SpringApplication从application.properties文件加载属性并将它们添加到Spring环境中
关于java - Spring Boot 使用 ConfigurationProperties 从 .properties 和 .yaml 注入(inject)映射值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57422752/