测试读取外部 YML 文件的 Spring 配置属性不起作用

问题描述

我正在使用 Spring Boot 2.4.8,我正在从外部 YML 文件读取信息读入 bean:

@Component
@ConfigurationProperties(prefix = "my.conf")
@PropertySource(value = "classpath:ext.yml",factory = YamlPropertySourceFactory.class)
public class MyExternalConfProp {
  private String property;
  
  public void setProperty(String property) {
    this.property = property;
  }

  public String getproperty() {
    return property;
  }
}

我定义了一个自定义工厂来读取外部 YML 文件,如文章 @PropertySource with YAML Files in Spring Boot 中所述:

public class YamlPropertySourceFactory implements PropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(String name,EncodedResource encodedResource) {
        YamlPropertiesfactorybean factory = new YamlPropertiesfactorybean();
        factory.setResources(encodedResource.getResource());

        Properties properties = factory.getobject();

        return new PropertiesPropertySource(
            Objects.requireNonNull(encodedResource.getResource().getFilename()),Objects.requireNonNull(properties));
    }

}

YML文件内容如下:

my.conf.property: yeyeye

问题是我找不到合适的切片来单独测试配置属性。事实上,以下测试失败了:

@SpringBoottest(classes = {MyExternalConfProp.class})
class MyExternalConfPropTest {

  @Autowired
  private MyExternalConfProp confProp;

  @Test
  void externalConfigurationPropertyShouldBeLoadedIntoSpringContext() {
    assertthat(confProp).hasFieldOrPropertyWithValue("property","yeyeye");
  }
}

正如我们所说,测试失败并显示以下消息:

java.lang.AssertionError: 
Expecting
  <in.rcard.externalconfprop.MyExternalConfProp@4cb40e3b>
to have a property or a field named <"property"> with value
  <"yeyeye">
but value was:
  <null>

然而,如果我不使用任何切片,则测试成功:

@SpringBoottest
class ExternalConfPropApplicationTests {

    @Autowired
    private MyExternalConfProp confProp;

    @Test
    void contextLoads() {
        assertthat(confProp).hasFieldOrPropertyWithValue("property","yeyeye");
    }

}

我该如何解决这个问题?是否有一些初始化程序或类似的东西可以添加切片以使测试成功?

Here 你可以在 GitHub 上找到整个项目。

解决方法

将@EnableConfigurationProperties 添加到您的测试中或在您的测试中启动 spring boot 应用程序将解决问题

@EnableConfigurationProperties
@SpringBootTest(classes = {MyExternalConfProp.class})
class MyExternalConfPropTest {

  @Autowired
  private MyExternalConfProp confProp;

  @Test
  void externalConfigurationPropertyShouldBeLoadedIntoSpringContext() {
    assertThat(confProp).hasFieldOrPropertyWithValue("property","yeyeye");
  }
}

@SpringBootTest(classes = {YourSpringBootApplication.class})
class MyExternalConfPropTest {

  @Autowired
  private MyExternalConfProp confProp;

  @Test
  void externalConfigurationPropertyShouldBeLoadedIntoSpringContext() {
    assertThat(confProp).hasFieldOrPropertyWithValue("property","yeyeye");
  }
}