From 352e3ca3976c5d77254f30c2a287b5894817c2f0 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 25 Sep 2017 12:36:34 +0100 Subject: [PATCH] Polish "Add auto-configuration for REST Docs with REST Assured" Closes gh-9643 --- spring-boot-docs/pom.xml | 8 +++ .../main/asciidoc/spring-boot-features.adoc | 47 +++++++++++++--- .../AdvancedConfigurationExample.java | 39 ++++++++++++++ .../restassured/UserDocumentationTests.java | 53 +++++++++++++++++++ .../restdocs/RestDocsAutoConfiguration.java | 10 ++-- .../RestDocsRestAssuredBuilderCustomizer.java | 2 +- ...dvancedConfigurationIntegrationTests.java} | 5 +- ...ocsAutoConfigurationIntegrationTests.java} | 4 +- ...dvancedConfigurationIntegrationTests.java} | 24 +++++---- ...ocsAutoConfigurationIntegrationTests.java} | 19 +++---- 10 files changed, 175 insertions(+), 36 deletions(-) create mode 100644 spring-boot-docs/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/restassured/AdvancedConfigurationExample.java create mode 100644 spring-boot-docs/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/restassured/UserDocumentationTests.java rename spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/{RestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java => MockMvcRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java} (94%) rename spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/{RestDocsAutoConfigurationIntegrationTests.java => MockMvcRestDocsAutoConfigurationIntegrationTests.java} (94%) rename spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/{RestAssuredAutoConfigurationAdvancedConfigurationIntegrationTests.java => RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java} (79%) rename spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/{RestAssuredAutoConfigurationIntegrationTests.java => RestAssuredRestDocsAutoConfigurationIntegrationTests.java} (80%) diff --git a/spring-boot-docs/pom.xml b/spring-boot-docs/pom.xml index 4ce316868f..57d6bf846c 100644 --- a/spring-boot-docs/pom.xml +++ b/spring-boot-docs/pom.xml @@ -55,6 +55,14 @@ org.springframework.boot spring-boot-test-autoconfigure + + io.rest-assured + rest-assured + + + org.springframework.restdocs + spring-restdocs-restassured + ch.qos.logback diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 481b17e61e..9ca8db743d 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -6279,8 +6279,20 @@ A list of the auto-configuration that is enabled by `@RestClientTest` can be [[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs]] ==== Auto-configured Spring REST Docs tests The `@AutoConfigureRestDocs` annotation can be used if you want to use Spring REST Docs -in your tests. It will automatically configure `MockMvc` to use Spring REST Docs and -remove the need for Spring REST Docs' JUnit rule. +in your tests with Mock MVC or REST Assured. It removes the need for Spring REST Docs' +JUnit rule. + +`@AutoConfigureRestDocs` can be used to override the default output directory +(`target/generated-snippets` if you are using Maven or `build/generated-snippets` if you +are using Gradle). It can also be used to configure the host, scheme, and port that will +appear in any documented URIs. + +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs-mock-mvc]] +===== Auto-configured Spring REST Docs tests with Mock MVC + +`@AutoConfigureRestDocs` customizes the `MockMvc` bean to use Spring REST Docs, Inject it +using `@Autowired` and use it in your tests as you normally would when using Mock MVC and +Spring REST Docs: [source,java,indent=0] ---- @@ -6315,11 +6327,9 @@ remove the need for Spring REST Docs' JUnit rule. } ---- -`@AutoConfigureRestDocs` can be used to override the default output directory -(`target/generated-snippets` if you are using Maven or `build/generated-snippets` if you -are using Gradle). It can also be used to configure the host, scheme, and port that will -appear in any documented URIs. If you require more control over Spring REST Docs' -configuration a `RestDocsMockMvcConfigurationCustomizer` bean can be used: +If you require more control over Spring REST Docs' configuration than offered by the +attributes of `@AutoConfigureRestDocs`, a `RestDocsMockMvcConfigurationCustomizer` bean +can be used: [source,java,indent=0] ---- @@ -6355,6 +6365,29 @@ automatically generate the default snippets: +[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs-rest-assured]] +===== Auto-configured Spring REST Docs tests with REST Assured + +`@AutoConfigureRestDocs` makes a `RequestSpecification` bean, preconfigured to use Spring REST +Docs, available to your tests. Inject it using `@Autowired` and use it in your tests as you +normally would when using REST Assured and Spring REST Docs: + +[source,java,indent=0] +---- +include::{code-examples}/test/autoconfigure/restdocs/restassured/UserDocumentationTests.java[tag=source] +---- + +If you require more control over Spring REST Docs' configuration than offered by the +attributes of `@AutoConfigureRestDocs`, a `RestDocsRestAssuredConfigurationCustomizer` +bean can be used: + +[source,java,indent=0] +---- +include::{code-examples}/test/autoconfigure/restdocs/restassured/AdvancedConfigurationExample.java[tag=configuration] +---- + + + [[boot-features-testing-spring-boot-applications-with-spock]] ==== Using Spock to test Spring Boot applications If you wish to use Spock to test a Spring Boot application you should add a dependency diff --git a/spring-boot-docs/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/restassured/AdvancedConfigurationExample.java b/spring-boot-docs/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/restassured/AdvancedConfigurationExample.java new file mode 100644 index 0000000000..87d9404b27 --- /dev/null +++ b/spring-boot-docs/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/restassured/AdvancedConfigurationExample.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.test.autoconfigure.restdocs.restassured; + +import org.springframework.boot.test.autoconfigure.restdocs.RestDocsRestAssuredConfigurationCustomizer; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.restdocs.restassured3.RestAssuredRestDocumentationConfigurer; +import org.springframework.restdocs.templates.TemplateFormats; + +public class AdvancedConfigurationExample { + + // tag::configuration[] + @TestConfiguration + public static class CustomizationConfiguration + implements RestDocsRestAssuredConfigurationCustomizer { + + @Override + public void customize(RestAssuredRestDocumentationConfigurer configurer) { + configurer.snippets().withTemplateFormat(TemplateFormats.markdown()); + } + + } + // end::configuration[] + +} diff --git a/spring-boot-docs/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/restassured/UserDocumentationTests.java b/spring-boot-docs/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/restassured/UserDocumentationTests.java new file mode 100644 index 0000000000..84578e1e95 --- /dev/null +++ b/spring-boot-docs/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/restassured/UserDocumentationTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.test.autoconfigure.restdocs.restassured; + +// tag::source[] +import io.restassured.specification.RequestSpecification; +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.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.test.context.junit4.SpringRunner; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; +import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@AutoConfigureRestDocs +public class UserDocumentationTests { + + @LocalServerPort + private int port; + + @Autowired + private RequestSpecification documentationSpec; + + @Test + public void listUsers() throws Exception { + given(this.documentationSpec).filter(document("list-users")).when() + .port(this.port).get("/").then().assertThat().statusCode(is(200)); + } + +} +// end::source[] diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsAutoConfiguration.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsAutoConfiguration.java index c1136f96dd..7941b6cb1e 100644 --- a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsAutoConfiguration.java +++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsAutoConfiguration.java @@ -45,11 +45,12 @@ import org.springframework.restdocs.restassured3.RestAssuredRestDocumentationCon */ @Configuration @EnableConfigurationProperties +@ConditionalOnWebApplication public class RestDocsAutoConfiguration { @Configuration - @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass(MockMvcRestDocumentation.class) + @ConditionalOnWebApplication(type = Type.SERVLET) static class RestDocsMockMvcAutoConfiguration { @Bean @@ -79,7 +80,8 @@ public class RestDocsAutoConfiguration { } @Configuration - @ConditionalOnClass({ RequestSpecification.class, RestAssuredRestDocumentation.class }) + @ConditionalOnClass({ RequestSpecification.class, + RestAssuredRestDocumentation.class }) static class RestDocsRestAssuredAutoConfiguration { @Bean @@ -89,7 +91,8 @@ public class RestDocsAutoConfiguration { RestDocumentationContextProvider contextProvider) { RestAssuredRestDocumentationConfigurer configurer = RestAssuredRestDocumentation .documentationConfiguration(contextProvider); - RestDocsRestAssuredConfigurationCustomizer configurationCustomizer = configurationCustomizerProvider.getIfAvailable(); + RestDocsRestAssuredConfigurationCustomizer configurationCustomizer = configurationCustomizerProvider + .getIfAvailable(); if (configurationCustomizer != null) { configurationCustomizer.customize(configurer); } @@ -105,5 +108,4 @@ public class RestDocsAutoConfiguration { } - } diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsRestAssuredBuilderCustomizer.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsRestAssuredBuilderCustomizer.java index f5b5335a33..54c600d3c8 100644 --- a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsRestAssuredBuilderCustomizer.java +++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsRestAssuredBuilderCustomizer.java @@ -22,7 +22,7 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.util.StringUtils; /** - * A customizer that configures Spring REST Docs with RestAssured. + * A customizer that configures Spring REST Docs with REST Assured. * * @author Eddú Meléndez */ diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/MockMvcRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java similarity index 94% rename from spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java rename to spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/MockMvcRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java index a13c0230d9..6c34911ccd 100644 --- a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/MockMvcRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java @@ -41,14 +41,15 @@ import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.li import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; /** - * Tests for {@link AutoConfigureRestDocs}. + * Integration tests for advanced configuration of {@link AutoConfigureRestDocs} with Mock + * MVC. * * @author Andy Wilkinson */ @RunWith(SpringRunner.class) @WebMvcTest(controllers = RestDocsTestController.class, secure = false) @AutoConfigureRestDocs -public class RestDocsAutoConfigurationAdvancedConfigurationIntegrationTests { +public class MockMvcRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests { @Before public void deleteSnippets() { diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsAutoConfigurationIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/MockMvcRestDocsAutoConfigurationIntegrationTests.java similarity index 94% rename from spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsAutoConfigurationIntegrationTests.java rename to spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/MockMvcRestDocsAutoConfigurationIntegrationTests.java index becb943dfe..c385376012 100644 --- a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsAutoConfigurationIntegrationTests.java +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/MockMvcRestDocsAutoConfigurationIntegrationTests.java @@ -34,14 +34,14 @@ import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.docu import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; /** - * Tests for {@link RestDocsAutoConfiguration}. + * Integration tests for {@link RestDocsAutoConfiguration} with Mock MVC. * * @author Andy Wilkinson */ @RunWith(SpringRunner.class) @WebMvcTest @AutoConfigureRestDocs(uriScheme = "https", uriHost = "api.example.com", uriPort = 443) -public class RestDocsAutoConfigurationIntegrationTests { +public class MockMvcRestDocsAutoConfigurationIntegrationTests { @Before public void deleteSnippets() { diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredAutoConfigurationAdvancedConfigurationIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java similarity index 79% rename from spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredAutoConfigurationAdvancedConfigurationIntegrationTests.java rename to spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java index 86e8db8388..12a940d5d3 100644 --- a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredAutoConfigurationAdvancedConfigurationIntegrationTests.java +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests.java @@ -42,14 +42,15 @@ import static org.springframework.restdocs.restassured3.RestAssuredRestDocumenta import static org.springframework.restdocs.restassured3.operation.preprocess.RestAssuredPreprocessors.modifyUris; /** - * Tests for {@link AutoConfigureRestDocs}. + * Integration tests for advanced configuration of {@link AutoConfigureRestDocs} with REST + * Assured. * * @author Eddú Meléndez */ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @AutoConfigureRestDocs -public class RestAssuredAutoConfigurationAdvancedConfigurationIntegrationTests { +public class RestAssuredRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests { @LocalServerPort private int port; @@ -65,15 +66,16 @@ public class RestAssuredAutoConfigurationAdvancedConfigurationIntegrationTests { @Test public void snippetGeneration() throws Exception { given(this.documentationSpec) - .filter(document("default-snippets", preprocessRequest(modifyUris() - .scheme("https").host("api.example.com").removePort()))).when() - .port(this.port).get("/").then().assertThat().statusCode(is(200)); + .filter(document("default-snippets", + preprocessRequest(modifyUris().scheme("https") + .host("api.example.com").removePort()))) + .when().port(this.port).get("/").then().assertThat().statusCode(is(200)); File defaultSnippetsDir = new File("target/generated-snippets/default-snippets"); assertThat(defaultSnippetsDir).exists(); - assertThat(new File(defaultSnippetsDir, "curl-request.md")).has( - contentContaining("'https://api.example.com/'")); - assertThat(new File(defaultSnippetsDir, "http-request.md")).has( - contentContaining("api.example.com")); + assertThat(new File(defaultSnippetsDir, "curl-request.md")) + .has(contentContaining("'https://api.example.com/'")); + assertThat(new File(defaultSnippetsDir, "http-request.md")) + .has(contentContaining("api.example.com")); assertThat(new File(defaultSnippetsDir, "http-response.md")).isFile(); } @@ -82,8 +84,8 @@ public class RestAssuredAutoConfigurationAdvancedConfigurationIntegrationTests { } @TestConfiguration - public static class CustomizationConfiguration implements - RestDocsRestAssuredConfigurationCustomizer { + public static class CustomizationConfiguration + implements RestDocsRestAssuredConfigurationCustomizer { @Override public void customize(RestAssuredRestDocumentationConfigurer configurer) { diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredAutoConfigurationIntegrationTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java similarity index 80% rename from spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredAutoConfigurationIntegrationTests.java rename to spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java index adc73336f4..bb83866447 100644 --- a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredAutoConfigurationIntegrationTests.java +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/restdocs/RestAssuredRestDocsAutoConfigurationIntegrationTests.java @@ -39,14 +39,14 @@ import static org.springframework.restdocs.restassured3.RestAssuredRestDocumenta import static org.springframework.restdocs.restassured3.operation.preprocess.RestAssuredPreprocessors.modifyUris; /** - * Tests for {@link RestDocsAutoConfiguration} + * Integration tests for {@link RestDocsAutoConfiguration} with REST Assured. * * @author Eddú Meléndez */ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @AutoConfigureRestDocs -public class RestAssuredAutoConfigurationIntegrationTests { +public class RestAssuredRestDocsAutoConfigurationIntegrationTests { @LocalServerPort private int port; @@ -62,15 +62,16 @@ public class RestAssuredAutoConfigurationIntegrationTests { @Test public void defaultSnippetsAreWritten() throws Exception { given(this.documentationSpec) - .filter(document("default-snippets", preprocessRequest(modifyUris() - .scheme("https").host("api.example.com").removePort()))).when() - .port(this.port).get("/").then().assertThat().statusCode(is(200)); + .filter(document("default-snippets", + preprocessRequest(modifyUris().scheme("https") + .host("api.example.com").removePort()))) + .when().port(this.port).get("/").then().assertThat().statusCode(is(200)); File defaultSnippetsDir = new File("target/generated-snippets/default-snippets"); assertThat(defaultSnippetsDir).exists(); - assertThat(new File(defaultSnippetsDir, "curl-request.adoc")).has( - contentContaining("'https://api.example.com/'")); - assertThat(new File(defaultSnippetsDir, "http-request.adoc")).has( - contentContaining("api.example.com")); + assertThat(new File(defaultSnippetsDir, "curl-request.adoc")) + .has(contentContaining("'https://api.example.com/'")); + assertThat(new File(defaultSnippetsDir, "http-request.adoc")) + .has(contentContaining("api.example.com")); assertThat(new File(defaultSnippetsDir, "http-response.adoc")).isFile(); }