Test on Spring configuration properties reading an external YML file doesn't work

Viewed 436

I'm working with Spring Boot 2.4.8, and I'm reading into a bean the information read from an external YML file:

@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;
  }
}

I defined a custom factory to read external YML files, as stated here in the article @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));
    }

}

The content of the YML file is the following:

my.conf.property: yeyeye

The problem is that I cannot find a proper slice to test the configuration property in isolation. In fact, the following test fails:

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

  @Autowired
  private MyExternalConfProp confProp;

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

As we said, the test fails with the following message:

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>

Whereas, if I don't use any slice, the test succeeds:

@SpringBootTest
class ExternalConfPropApplicationTests {

    @Autowired
    private MyExternalConfProp confProp;

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

}

How can I resolve this? Is it some initializer or something similar that I can add to the slice to make the test succeed?

Here you can find the whole project on GitHub.

1 Answers

Add @EnableConfigurationProperties to your test or start the spring boot application on your test will solve the problem

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

  @Autowired
  private MyExternalConfProp confProp;

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

or

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

  @Autowired
  private MyExternalConfProp confProp;

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