当前位置: 首页 > 知识库问答 >
问题:

在测试中使用Spring@ConfigurationProperties读取映射

宗政才俊
2023-03-14

根据Spring Boot integration tests不读取属性文件的建议,我创建了以下代码,目的是从我的JUnit测试中的属性读取映射。(我使用的是yml格式,并且使用@configurationproperties而不是@value)

@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(locations="classpath:application-test.yml")
@ContextConfiguration(classes = {PropertiesTest.ConfigurationClass.class, PropertiesTest.ClassToTest.class})
public class PropertiesTest {

    @Configuration
    @EnableConfigurationProperties
    static class ConfigurationClass {
    }


    @ConfigurationProperties
    static class ClassToTest {
        private String test;

        private Map<String, Object> myMap = new HashMap<>();

        public String getTest() {
            return test;
        }

        public void setTest(String test) {
            this.test = test;
        }

        public Map<String, Object> getMyMap() {
            return myMap;
        }

    }

    @Autowired
    private ClassToTest config;


    @Test
    public void testStringConfig() {
        Assert.assertEquals(config.test, "works!");
    }

    @Test
    public void testMapConfig() {
        Assert.assertEquals(config.myMap.size(), 1);
    }

}

我的测试配置(在application-test.yml中):

test: works!
myMap:
  aKey: aVal
  aKey2: aVal2

奇怪的是,弦“起作用了!”从配置文件中成功读取,但未填充映射。

注意:添加映射设置程序会导致以下异常

Caused by: org.springframework.validation.BindException: org.springframework.boot.bind.RelaxedDataBinder$RelaxedBeanPropertyBindingResult: 1 errors
Field error in object 'target' on field 'myMap': rejected value []; codes [typeMismatch.target.myMap,typeMismatch.myMap,typeMismatch.java.util.Map,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.myMap,myMap]; arguments []; default message [myMap]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Map' for property 'myMap'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.util.Map' for property 'myMap': no matching editors or conversion strategy found]
    at org.springframework.boot.bind.PropertiesConfigurationFactory.checkForBindingErrors(PropertiesConfigurationFactory.java:359)
    at org.springframework.boot.bind.PropertiesConfigurationFactory.doBindPropertiesToTarget(PropertiesConfigurationFactory.java:276)
    at org.springframework.boot.bind.PropertiesConfigurationFactory.bindPropertiesToTarget(PropertiesConfigurationFactory.java:240)
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:330)
    ... 42 more

共有1个答案

广晔
2023-03-14

在使用调试器后,我相信这是TestPropertySourceUtils.addPropertiesFilestoEnvironment()中的一个bug/缺失特性:

try {
    for (String location : locations) {
        String resolvedLocation = environment.resolveRequiredPlaceholders(location);
        Resource resource = resourceLoader.getResource(resolvedLocation);
        environment.getPropertySources().addFirst(new ResourcePropertySource(resource));
    }
}

ResourcePropertySource只能处理.properties文件,而不能处理.yml。在常规应用程序中,YamlPropertySourceLoader注册并可以处理.yml

请注意:TestPropertySourceUtils.AddPropertiesFilestoEnvironment()由以下人员调用

org.springframework.test.context.support.DelegatingSmartContextLoader.prepareContext()

如果在@contextconfiguration中没有指定加载程序,则DelegatingSmartContextLoader是您接收的默认上下文加载程序。(实际上@contextconfiguration指定接口,但AbstractTestContextBootstrapper.resolvecontextLoader()将其更改为具体类)

为了解决这个问题,我将配置更改为application-test.properties,并在测试中使用了该文件。

test=works!
myMap.aKey: aVal

另一个评论:不需要地图上的setter:

 类似资料: