Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring: @BootstrapWith for ApplicationContext

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

like image 593
Anton Avatar asked Jul 08 '26 17:07

Anton


2 Answers

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.

like image 140
Maciej Dobrowolski Avatar answered Jul 10 '26 06:07

Maciej Dobrowolski


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

like image 21
Brad Avatar answered Jul 10 '26 06:07

Brad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!