I am using Microprofile Config (@Inject
, not ConfigProvider
) in my application. I have a configuration that takes different branches for different values. In order to test (Arquillian
) all paths in my code, I need to be able to change this value at runtime. Can someone offer tips on how to achieve this? My properties are set using system properties, but I'm open to ideas on how to handle this.

- 329
- 2
- 12
2 Answers
You could register a ConfigSource
which can be configured easily.
You can look at the one I wrote one for the mp-config TCK itself:
https://github.com/eclipse/microprofile-config/blob/master/tck/src/main/java/org/eclipse/microprofile/config/tck/configsources/ConfigurableConfigSource.java
For adding this ConfigSource to your Arquillian @Deployment check this test: https://github.com/eclipse/microprofile-config/blob/1499b7bf734eb1710fe3b7fbdbbcb1ca0983e4cd/tck/src/main/java/org/eclipse/microprofile/config/tck/ConfigAccessorTest.java#L52
The important lines are:
.addClass(ConfigurableConfigSource.class)
.addAsServiceProvider(ConfigSource.class, ConfigurableConfigSource.class)
And then tweak the values
ConfigurableConfigSource.configure(config, "my.config.entry", "some new value");

- 730
- 5
- 12
-
My only concern for this implementation, is if it will work for simple bean values, such as [the following](https://github.com/eclipse/microprofile-config/blob/1499b7bf734eb1710fe3b7fbdbbcb1ca0983e4cd/tck/src/main/java/org/eclipse/microprofile/config/tck/SimpleValuesBean.java#L37-L39). Can you address this concern? Also, `onAttributeChange` does not seem to be in a release version yet, so I will eagerly wait for it to come. – James Mar 12 '19 at 15:25
-
You don't need `onAttributeChange` for the task you want. It's just in there because the current TCK already implements the newer mp-config API. Just leave this part out. Regarding the @Dependent SimpleValuesBean: of course if you inject a java native type into a class then it will not pick up any changes in the underlying config due to being final. Use a Provider
for it for example. – struberg Mar 31 '19 at 20:20
Regarding to the Microprofile Config: Spec: Configsource which mentions as the following: -
System properties (default ordinal=400).
Environment variables (default ordinal=300).
A ConfigSource for each property file META-INF/microprofile-config.properties found on the classpath. (default ordinal = 100).
This means the system properties
is a highest priority here. Then we may set the default value at the META-INF/microprofile-config.properties
and override it if needed by the system properties
instead.
During the integration test we are able to set the system properties
together with use the javax.inject.Provider
to make it retrieving dynamically so that the default value is overridden as the following example :-
# META-INF/microprofile-config.properties
my.key=original
import javax.inject.Inject;
import javax.inject.Provider;
import org.eclipse.microprofile.config.inject.ConfigProperty;
public class SomeClass {
@Inject
@ConfigProperty(
name = "my.key"
)
private Provider<String> key1;
public String doSomethingWithConfig() {
return key1.get();
}
}
import javax.inject.Inject;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.junit.Test;
import org.junit.Assert;
@RunWith(Arquillian.class)
public class SomeClassTester {
@Inject
private SomeClass someclass;
@Test
@InSequence(1)
public void whenTestDefaultConfig() {
Assert.assertEquals("The value must be a defualt.",
"original",
this.someclass.doSomethingWithConfig());
}
@Test
@InSequence(2)
public void whenTestOverrideMPConfig() {
System.setProperty("my.key",
"new-value");
Assert.assertEquals("The value must be overridden",
"new-value",
this.someclass.doSomethingWithConfig());
}
}
EDIT1
Furthermore if we would like to take control over the system properites
, the System Rules will make our live easier. They provide ClearSystemProperties, ProvideSystemProperty and RestoreSystemProperties as the following example from their document.
public class MyTest {
@Rule
public final RestoreSystemProperties restoreSystemProperties
= new RestoreSystemProperties();
@Test
public void overrideProperty() {
//after the test the original value of "MyProperty" will be restored.
System.setProperty("MyProperty", "other value");
...
}
}

- 8,847
- 2
- 56
- 71
-
1`System.setProperty` will surely work. But be careful when running tests in parallel. You might use an own custom ConfigurableConfigSource with stores the config in a @RequestScoped bean to isolate between different threads. – struberg Mar 31 '19 at 20:23