3

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.

riccardo.cardin
  • 7,971
  • 5
  • 57
  • 106

1 Answers1

0

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");
  }
}
Ben Miao
  • 1
  • 2
  • I'm using a `@ConfigurationProperties` because I don't want to use the `@Value` annotation :) The read bean might have a very complex structure to load. – riccardo.cardin Jul 14 '21 at 09:18
  • yeah, that's odd, @ConfigurationProperties should work, but it doesn't, I try to add the ```@EnableConfigurationProperties```, but it still doesn't work – Ben Miao Jul 14 '21 at 09:51
  • I know. I suggest to remove the answer, and to post a new one when you'll have a solution :) – riccardo.cardin Jul 14 '21 at 10:00
  • check this out, it might solve your problem https://stackoverflow.com/questions/56234234/spring-boot-configuration-processor-is-not-working-on-maven-submodule-project – Ben Miao Jul 14 '21 at 10:16
  • How the SO question you shared should solve my problem? It's not even related :| – riccardo.cardin Jul 14 '21 at 10:20
  • @riccardo.cardin I found the solution for this issue, pls see my answer again :) – Ben Miao Jul 15 '21 at 11:28