Provide test auto-configuration for Spring REST Docs

This commit introduces a new annotation, @AutoConfigureRestDocs,
which can be used to enable auto-configuration of Spring REST Docs.
The auto-configuration removes the need to use Spring REST Docs' JUnit
rule and will automatically configure MockMvc. Combined with the new
auto-configuration for MockMvc it allows a test class to be free of
boilerplate configuration:

@RunWith(SpringRunner.class)
@WebMvcTest
@AutoConfigureRestDocs(outputDir = "target/generated-snippets",
        uriScheme = "https", uriHost = "api.example.com",
        uriPort = 443)
public class ExampleDocumentationTests {

    @Autowired
    private MockMvc mvc;

    @Test
    public void documentIndex() {
        // …
    }

}

For more advanced customization a RestDocsMockMvcConfigurationCustomizer
bean can be used.

If a RestDocumentationResultHandler is found in the context, it will
be passed to the ConfigurableMockMvcBuilder's alwaysDo method as part
of its customization.

Closes gh-5563
This commit is contained in:
Andy Wilkinson
2016-04-04 15:41:13 +01:00
parent f99bfccd51
commit eb3180d581
20 changed files with 854 additions and 77 deletions

View File

@@ -26,23 +26,19 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.Filter;
import groovy.text.Template;
import groovy.text.TemplateEngine;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoints;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringApplicationConfiguration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.restdocs.JUnitRestDocumentation;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
@@ -50,12 +46,9 @@ import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultHandler;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.util.StringUtils;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -65,40 +58,21 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@TestPropertySource(properties = { "spring.jackson.serialization.indent_output=true",
"endpoints.health.sensitive=true", "endpoints.actuator.enabled=false" })
@DirtiesContext
@AutoConfigureRestDocs(EndpointDocumentation.RESTDOCS_OUTPUT_DIR)
@AutoConfigureMockMvc
public class EndpointDocumentation {
private static final String RESTDOCS_OUTPUT_DIR = "target/generated-snippets";
@Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(
RESTDOCS_OUTPUT_DIR);
@Autowired
private WebApplicationContext context;
static final String RESTDOCS_OUTPUT_DIR = "target/generated-snippets";
@Autowired
private MvcEndpoints mvcEndpoints;
@Autowired
@Qualifier("metricFilter")
private Filter metricFilter;
@Autowired
@Qualifier("webRequestLoggingFilter")
private Filter traceFilter;
@Autowired
private TemplateEngine templates;
@Autowired
private MockMvc mockMvc;
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.addFilters(this.metricFilter, this.traceFilter)
.apply(documentationConfiguration(this.restDocumentation)).build();
}
@Test
public void logfile() throws Exception {
this.mockMvc.perform(get("/logfile").accept(MediaType.TEXT_PLAIN))

View File

@@ -16,25 +16,21 @@
package org.springframework.boot.actuate.hypermedia;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringApplicationConfiguration;
import org.springframework.http.MediaType;
import org.springframework.restdocs.JUnitRestDocumentation;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -44,23 +40,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@TestPropertySource(properties = { "spring.jackson.serialization.indent_output=true",
"endpoints.health.sensitive=false" })
@DirtiesContext
@AutoConfigureMockMvc
@AutoConfigureRestDocs("target/generated-snippets")
public class HealthEndpointDocumentation {
@Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(
"target/generated-snippets");
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation)).build();
}
@Test
public void health() throws Exception {
this.mockMvc.perform(get("/health").accept(MediaType.APPLICATION_JSON))

View File

@@ -16,25 +16,21 @@
package org.springframework.boot.actuate.hypermedia;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringApplicationConfiguration;
import org.springframework.http.MediaType;
import org.springframework.restdocs.JUnitRestDocumentation;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -43,23 +39,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@WebAppConfiguration
@TestPropertySource(properties = "spring.jackson.serialization.indent_output=true")
@DirtiesContext
@AutoConfigureMockMvc
@AutoConfigureRestDocs("target/generated-snippets")
public class HypermediaEndpointDocumentation {
@Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(
"target/generated-snippets");
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation)).build();
}
@Test
public void beans() throws Exception {
this.mockMvc.perform(get("/beans").accept(MediaType.APPLICATION_JSON))

View File

@@ -21,9 +21,14 @@ import groovy.text.TemplateEngine;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
// Flyway must go first
@SpringBootApplication
@Import({ FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class })
public class SpringBootHypermediaApplication {
@Bean