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:
@ContextConfiguration(classes = Config.class, initializers = ConfigDataApplicationContextInitializer.class)
class MyConfigFileTests {
// ...
}
@ContextConfiguration(classes = [Config::class], initializers = [ConfigDataApplicationContextInitializer::class])
class MyConfigFileTests {
// ...
}
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 TestPropertyValues
class allows you to quickly add properties to a
ConfigurableEnvironment
or ConfigurableApplicationContext
. You can call it using the lines
key=value
, as shown below:
class MyEnvironmentTests {
@Test
void testPropertySources() {
MockEnvironment environment = new MockEnvironment();
TestPropertyValues.of("org=Spring", "name=Boot").applyTo(environment);
assertThat(environment.getProperty("name")).isEqualTo("Boot");
}
}
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 into your test class constructor or test method like this:
@ExtendWith(OutputCaptureExtension.class)
class MyOutputCaptureTests {
@Test
void testName(CapturedOutput output) {
System.out.println("Hello World!");
assertThat(output).contains("World");
}
}
@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.
WebTestClient
that is well
suited for both integration tests in WebFlux and 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:
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");
}
}
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 implement 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:
@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));
}
}
}
@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))
}
}
}
GO TO FULL VERSION