Search

Dark theme | Light theme

October 24, 2024

Helidon SE Helpings: Default Configuration Sources During Testing

In a previous blog post we learned about the default input sources that are used by Helidon SE. The list of input sources is different based on which artifacts are on the classpath of our application. When we write tests for code in our application that uses the default configuration created by Config.create() we must take into account that different input sources are used. Also here it is based on the artifacts that are on the classpath. That means that different files with configuration data are loaded, eg. a file application-test.conf when we have the artifact helidon-config-hocon and a file application-test.yml if the artifact helidon-config-yaml is on the classpath.

If we use the artifact helidon-config then the following input sources are searched with the following order of preference:

  1. System environment variables
  2. Java system properties
  3. a file META-INF/microprofile-config-test.properties on the classpath,
  4. a file META-INF/microprofile-config.properties on the classpath.

Notice that there is no input source that looks for a file application.properties on the classpath, but when we run our application that is a valid input source. Also the order of the input sources system environment variables and Java system properties switched. So the input sources for a default configuration created with Config.create() is different during run-time and when we test our application.

In the following test we create a default configuration using Config.create() and get the configuration property app.message that is set using a system environment variable, Java system property and the file META-INF/microprofile-config-test.properties placed in src/test/resources (which will be on the classpath). In order to test with setting a system environment variable in our test code we use the library com.github.stefanbirkner:system-lambda by adding the following dependency:

<dependency>
    <groupId>com.github.stefanbirkner</groupId>
    <artifactId>system-lambda</artifactId>
    <version>1.2.1</version>
    <scope>test</scope>
</dependency>

Our properties file looks like this:

# File: src/test/resources/META-INF/microprofile-config-test.properties
app.message=Hello from classpath:META-INF/microprofile-config-test.properties

Our test class has three test methods to check the value of the configuration property app.message:

// File: src/test/java/mrhaki/helidon/DefaultConfigTest.java
package mrhaki.helidon;

import io.helidon.config.Config;
import org.junit.jupiter.api.Test;

import static com.github.stefanbirkner.systemlambda.SystemLambda.restoreSystemProperties;
import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable;
import static org.assertj.core.api.Assertions.assertThat;

public class DefaultConfigTest {

    @Test
    void defaultConfig() throws Exception {
        // expect
        withEnvironmentVariable("APP_MESSAGE", "Hello from environment variable")
                .execute(() -> {
                    final Config config = Config.create();

                    assertThat(config.get("app.message").asString().asOptional())
                            .hasValue("Hello from environment variable");
                });
    }

    @Test
    void withSystemProperties() throws Exception {
        restoreSystemProperties(() -> {
            System.setProperty("app.message", "Hello from Java system property");
            assertThat(Config.create().get("app.message").asString().asOptional())
                    .hasValue("Hello from Java system property");
        });
    }

    @Test
    void withConfigTestProperties() {
        // given
        final Config config = Config.create();

        // expect
        assertThat(config.get("app.message").asString().asOptional())
                .hasValue("Hello from classpath:META-INF/microprofile-config-test.properties");
    }
}

When we apply the artifact helidon-config-hocon in our pom.xml file then the following input sources are searched with the following order of preference:

  1. System environment variables,
  2. Java system properties,
  3. a file application-test.json,
  4. a file application-test.conf,
  5. classpath:application-test.json,
  6. a file application-test.conf on the classpath,
  7. a file application.json,
  8. a file application.conf,
  9. a file application.json on the classpath,
  10. a file application.conf on the classpath,
  11. a file META-INF/microprofile-config-test.properties on the classpath,
  12. a file META-INF/microprofile-config.properties.` on the classpath

If we would use the artifact helidon-config-yaml then the following input sources are searched with the following order of preference:

  1. System environment variables,
  2. Java system properties,
  3. a file application-test.yml,
  4. a file application-test.yaml,
  5. a file application-test.yml on the classpath,
  6. a file application-test.yaml on the classpath,
  7. a file application.yml,
  8. a file application.yaml,
  9. a file application.yml on the classpath,
  10. a file application.yaml on the classpath,
  11. a file META-INF/microprofile-config-test.properties on the classpath,
  12. a file META-INF/microprofile-config.properties on the classpath.

Written with Helidon SE 4.2.1.