Currently I use @BootstrapWith annotation in conjunction with custom class, which is simply sets some system properties used in test. However (as far as I understand it) those properties are being set each time TestContextManager instantiates test and TestContext with it:
@BootstrapWith is a class-level annotation that is used to configure how the Spring TestContext Framework is bootstrapped
spring.io
Is there any way to set properties once before ApplicationContext is started?
Edit:
I cannot use @RunWith(SpringJUnit4ClassRunner.class) due to parameterized tests, which require @RunWith(Parameterized.class). I use SpringClassRule and SpringMethodRule instead
Additionally I run not only parameterized tests, but ordinary tests as well. Thus I cannot simply extend Parameterized runner
I think that the most basic way of setting some properties before ApplicationContext sets up is to write custom runner, like that:
public class MyRunner extends SpringJUnit4ClassRunner {
public MyRunner(Class<?> clazz) throws InitializationError {
super(clazz);
System.setProperty("sample.property", "hello world!");
}
}
And then you can use it instead your current runner.
@RunWith(MyRunner.class)
@SpringBootTest
//....
If your current runner seems to be declared final, you can possibly use aggregation (but I have not tested in) instead of inheritance.
Here you can find a sample Gist where this runner is used and property gets successfully resolved.
update
If you don't want to use custom Runner (although you could have several runners setting properties for each case - with parameters, without parameters, and so on). You can use @ClassRule which works on static fields/methods - take a look at the example below:
@ClassRule
public static ExternalResource setProperties() {
return new ExternalResource() {
@Override
public Statement apply(Statement base, Description description) {
System.setProperty("sample.property", "hello world!");
return super.apply(base, description);
}
};
}
This static method is to be placed in your test class.
If it's just Properties that you want to add as part of the bootstrapping of the spring application context you can use the annotation @TestPropertySource at the top of your Junit test class like this...
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={SpringConfig.class,SpringConfigForTests.class})
@TestPropertySource(properties = "runDate=20180110")
public class AcceptanceTests {
...
I use this technique to load my production SpringConfig class (which loads properties files), then override some beans specifically for testing in SpringConfigForTests (and potentially loading test specific properties files), then adding the another run-time property named runDate.
I am using Spring 4.2.5.RELEASE and it looks like this annotation has been included since 4.1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With