ConfigDataApplicationContextInitializer

ConfigDataApplicationContextInitializer is an ApplicationContextInitializer that can be applied to tests to load application.properties files for Spring Boot. You can use it if you do not need the full set of functions provided by the @SpringBootTest annotation, as shown in the following example:

Java
import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;
import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration(classes = Config.class, initializers = ConfigDataApplicationContextInitializer.class)
class MyConfigFileTests {
    // ...
}
Kotlin
import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer
import org.springframework.test.context.ContextConfiguration
@ContextConfiguration(classes = [Config::class], initializers = [ConfigDataApplicationContextInitializer::class])
class MyConfigFileTests {
    // ...
}
Using solely the ConfigDataApplicationContextInitializer class will not provide support for embedding the @Value("${...​}") annotation . Its only job is to ensure that the application.properties files are loaded into the Environment for Spring. To support the @Value annotation, you must either additionally configure the PropertySourcesPlaceholderConfigurer, or use the @SpringBootTest annotation, which will automatically configure it for you.

TestPropertyValues

The Class TestPropertyValues allows you to quickly add properties to a ConfigurableEnvironment or ConfigurableApplicationContext. You can call it using the lines key=value, as shown below:

Java
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.mock.env.MockEnvironment;
import static org.assertj.core.api.Assertions.assertThat;
class MyEnvironmentTests {
    @Test
    void testPropertySources() {
        MockEnvironment environment = new MockEnvironment();
        TestPropertyValues.of("org=Spring", "name=Boot").applyTo(environment);
        assertThat(environment.getProperty("name")).isEqualTo("Boot");
    }
}
Kotlin
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.boot.test.util.TestPropertyValues
import org.springframework.mock.env.MockEnvironment
class MyEnvironmentTests {
    @Test
    fun testPropertySources() {
        val environment = MockEnvironment()
        TestPropertyValues.of("org=Spring", "name=Boot").applyTo(environment)
        assertThat(environment.getProperty("name")).isEqualTo("Boot")
    }
}

OutputCapture

OutputCapture is an Extension for JUnit that can be used to capture the output of System.out and System.err. To use, add the @ExtendWith(OutputCaptureExtension.class) annotation and inject CapturedOutput as an argument in your test class constructor or test method like this:

Java
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(OutputCaptureExtension.class)
class MyOutputCaptureTests {
    @Test
    void testName(CapturedOutput output) {
        System.out.println("Hello World!");
        assertThat(output).contains("World");
    }
}
Kotlin
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.boot.test.system.CapturedOutput
import org.springframework.boot.test.system.OutputCaptureExtension
@ExtendWith(OutputCaptureExtension::class)
class MyOutputCaptureTests {
    @Test
    fun testName(output: CapturedOutput?) {
        println("Hello World!")
        assertThat(output).contains("World")
    }
}

TestRestTemplate

TestRestTemplate is a convenient alternative to Spring's RestTemplate that is useful for integration tests. You can get a vanilla template or one that sends basic HTTP authentication (with username and password). In any case, the template is fault-tolerant. This means that its operating logic is convenient for testing and does not generate exceptions for errors 4xx and 5xx. Instead, such errors can be detected through the returned ResponseEntity and its status code.

Spring Framework 5.0 includes a new WebTestClient that is also good for integration tests in WebFlux, and for end-to-end testing in WebFlux and MVC. Unlike TestRestTemplate, it provides a fluid API for adding assertions.

It is recommended - although not required - to use the Apache HTTP Client (version 4.3.2 or higher). If it is in your classpath, the TestRestTemplate template will respond to this and configure the client accordingly. If you are using the Apache HTTP client, some additional features are added that are useful for testing:

  • Redirects are not tracked (so you can add claims for the response location).

  • Cookies are ignored (so the template does not save state).

An instance of TestRestTemplate can be created directly in integration tests, as shown in the following example:

Java
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.ResponseEntity;
import static org.assertj.core.api.Assertions.assertThat;
class MyTests {
    private final TestRestTemplate template = new TestRestTemplate();
    @Test
    void testRequest() {
        ResponseEntity<String> headers = this.template.getForEntity("https://myhost.example.com/example", String.class);
        assertThat(headers.getHeaders().getLocation()).hasHost("other.example.com");
    }
}
Kotlin
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.boot.test.web.client.TestRestTemplate
class MyTests {
    private val template = TestRestTemplate()
    @Test
    fun testRequest() {
        val headers = template.getForEntity("https://myhost.example.com/example", String::class.java)
        assertThat(headers.headers.location).hasHost("other.example.com")
    }
}

Additionally, if you use the @SpringBootTest annotation with WebEnvironment.RANDOM_PORT or WebEnvironment.DEFINED_PORT, you can inject a fully configured TestRestTemplate and start using it. If necessary, additional settings can be applied via the RestTemplateBuilder bean. Any URLs that do not specify a host and port are automatically connected to the built-in server, as shown in the following example:

Java
import java.time.Duration;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpHeaders;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MySpringBootTests {
    @Autowired
    private TestRestTemplate template;
    @Test
    void testRequest() {
        HttpHeaders headers = this.template.getForEntity("/example", String.class).getHeaders();
        assertThat(headers.getLocation()).hasHost("other.example.com");
    }
    @TestConfiguration(proxyBeanMethods = false)
    static class RestTemplateBuilderConfiguration {
        @Bean
        RestTemplateBuilder restTemplateBuilder() {
            return new RestTemplateBuilder().setConnectTimeout(Duration.ofSeconds(1))
                    .setReadTimeout(Duration.ofSeconds(1));
        }
    }
}
Kotlin
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.boot.test.web.client.TestRestTemplate
import org.springframework.boot.web.client.RestTemplateBuilder
import org.springframework.context.annotation.Bean
import java.time.Duration
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MySpringBootTests(@Autowired val template: TestRestTemplate) {
    @Test
    fun testRequest() {
        val headers = template.getForEntity("/example", String::class.java).headers
        assertThat(headers.location).hasHost("other.example.com")
    }
    @TestConfiguration(proxyBeanMethods = false)
    internal class RestTemplateBuilderConfiguration {
        @Bean
        fun restTemplateBuilder(): RestTemplateBuilder {
            return RestTemplateBuilder().setConnectTimeout(Duration.ofSeconds(1))
                .setReadTimeout(Duration.ofSeconds(1))
        }
    }
}