Search code examples
javaspring-bootjunitspring-test

Springboot test using ConfigurationProperties to fill Map


I have a generic class that i used to load some keys from my application yaml file ,here's my yaml file :

errabi.security:
  keyStores:
      jwt:
        type: JKS
        location: classpath:keystore.jks
        keyStorePassword: password # to be encrypted
        keyPassword: password # to be encrypted
        keyAlias: errabi
      jwe:
        type: JKS
        location: classpath:keystore.jks
        keyStorePassword: password # to be encrypted
        keyPassword: password # to be encrypted
        keyAlias: errabi

And here's the class the I use to load values based on some keys :

@Configuration
@ConfigurationProperties(prefix = "errabi.security")
public class KeyStoreConfig {

    private Map<String, KeyStoreConfig.KeyStoreConfiguration> keyStores;

    public Map<String, KeyStoreConfiguration> getKeyStores() {
        return keyStores;
    }

    public void setKeyStores(Map<String, KeyStoreConfiguration> keyStores) {
        this.keyStores = keyStores;
    }

    public static class KeyStoreConfiguration {
          private String type;
          private String location;
          private char [] keyStorePassword;
          private char [] keyPassword;
          private String keyAlias;
          // getters and setters
}
}

In my application when i call the method KeyStoreConfig.getKeyStores() i get the map with the key values , but in my test i still not able to inject the bean KeyStoreConfig

@SpringBootTest
@ContextConfiguration(classes = KeyStoreConfig.class)
class JWEUtilTest extends Specification {
    @Autowired
    private KeyStoreConfig keyStoreConfig;
    
    // in the debug mode the KeyStoreConfig.getKeyStores() return a null instead of a map with keyvalues
}

during my test i get a NullPointerException when i debug i see that the KeyStoreConfig.getKeyStores() return a null instead of a map with keyvalues did i miss something in my configuration ? thanks in advance for any help


Solution

  • So, since you're using the @ContextConfiguration annotation over the @SpringBootTest, it seems that some Spring Boot features are disabled, like loading of external properties specified in the application.properties or application.yaml.

    To enable it manually you should add to your test class: @EnableConfigurationProperties(KeyStoreConfig.class).

    Some helpful links about spring boot testing:

    Spring Boot Testing @ConfigurationProperties

    @SpringBootTest vs @ContextConfiguration vs @Import in Spring Boot

    I also found this article interesting, it's about difference between @ContextConfiguration and @SpringApplicationConfiguration, which is deprecated as of 1.4 spring boot version in favor of @SpringBootTest.