Skip to content

Commit d8cfae7

Browse files
committed
Merge pull request #9643 from Eddú Meléndez
* gh-9643: Polish "Add auto-configuration for REST Docs with REST Assured" Add auto-configuration for REST Docs with REST Assured
2 parents a1e26ea + 352e3ca commit d8cfae7

File tree

15 files changed

+529
-33
lines changed

15 files changed

+529
-33
lines changed

spring-boot-dependencies/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
<quartz.version>2.3.0</quartz.version>
151151
<querydsl.version>4.1.4</querydsl.version>
152152
<reactor-bom.version>Bismuth-RC1</reactor-bom.version>
153+
<rest-assured.version>3.0.2</rest-assured.version>
153154
<reactive-streams.version>1.0.1</reactive-streams.version>
154155
<rxjava.version>1.3.2</rxjava.version>
155156
<rxjava-adapter.version>1.2.1</rxjava-adapter.version>
@@ -906,6 +907,11 @@
906907
<artifactId>rxjava</artifactId>
907908
<version>${rxjava2.version}</version>
908909
</dependency>
910+
<dependency>
911+
<groupId>io.rest-assured</groupId>
912+
<artifactId>rest-assured</artifactId>
913+
<version>${rest-assured.version}</version>
914+
</dependency>
909915
<dependency>
910916
<groupId>io.searchbox</groupId>
911917
<artifactId>jest</artifactId>

spring-boot-docs/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@
5555
<groupId>org.springframework.boot</groupId>
5656
<artifactId>spring-boot-test-autoconfigure</artifactId>
5757
</dependency>
58+
<dependency>
59+
<groupId>io.rest-assured</groupId>
60+
<artifactId>rest-assured</artifactId>
61+
</dependency>
62+
<dependency>
63+
<groupId>org.springframework.restdocs</groupId>
64+
<artifactId>spring-restdocs-restassured</artifactId>
65+
</dependency>
5866
<!-- Optional deps required when generating Javadoc with Java 8 -->
5967
<dependency>
6068
<groupId>ch.qos.logback</groupId>

spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6279,8 +6279,20 @@ A list of the auto-configuration that is enabled by `@RestClientTest` can be
62796279
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs]]
62806280
==== Auto-configured Spring REST Docs tests
62816281
The `@AutoConfigureRestDocs` annotation can be used if you want to use Spring REST Docs
6282-
in your tests. It will automatically configure `MockMvc` to use Spring REST Docs and
6283-
remove the need for Spring REST Docs' JUnit rule.
6282+
in your tests with Mock MVC or REST Assured. It removes the need for Spring REST Docs'
6283+
JUnit rule.
6284+
6285+
`@AutoConfigureRestDocs` can be used to override the default output directory
6286+
(`target/generated-snippets` if you are using Maven or `build/generated-snippets` if you
6287+
are using Gradle). It can also be used to configure the host, scheme, and port that will
6288+
appear in any documented URIs.
6289+
6290+
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs-mock-mvc]]
6291+
===== Auto-configured Spring REST Docs tests with Mock MVC
6292+
6293+
`@AutoConfigureRestDocs` customizes the `MockMvc` bean to use Spring REST Docs, Inject it
6294+
using `@Autowired` and use it in your tests as you normally would when using Mock MVC and
6295+
Spring REST Docs:
62846296

62856297
[source,java,indent=0]
62866298
----
@@ -6315,11 +6327,9 @@ remove the need for Spring REST Docs' JUnit rule.
63156327
}
63166328
----
63176329

6318-
`@AutoConfigureRestDocs` can be used to override the default output directory
6319-
(`target/generated-snippets` if you are using Maven or `build/generated-snippets` if you
6320-
are using Gradle). It can also be used to configure the host, scheme, and port that will
6321-
appear in any documented URIs. If you require more control over Spring REST Docs'
6322-
configuration a `RestDocsMockMvcConfigurationCustomizer` bean can be used:
6330+
If you require more control over Spring REST Docs' configuration than offered by the
6331+
attributes of `@AutoConfigureRestDocs`, a `RestDocsMockMvcConfigurationCustomizer` bean
6332+
can be used:
63236333

63246334
[source,java,indent=0]
63256335
----
@@ -6355,6 +6365,29 @@ automatically generate the default snippets:
63556365

63566366

63576367

6368+
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs-rest-assured]]
6369+
===== Auto-configured Spring REST Docs tests with REST Assured
6370+
6371+
`@AutoConfigureRestDocs` makes a `RequestSpecification` bean, preconfigured to use Spring REST
6372+
Docs, available to your tests. Inject it using `@Autowired` and use it in your tests as you
6373+
normally would when using REST Assured and Spring REST Docs:
6374+
6375+
[source,java,indent=0]
6376+
----
6377+
include::{code-examples}/test/autoconfigure/restdocs/restassured/UserDocumentationTests.java[tag=source]
6378+
----
6379+
6380+
If you require more control over Spring REST Docs' configuration than offered by the
6381+
attributes of `@AutoConfigureRestDocs`, a `RestDocsRestAssuredConfigurationCustomizer`
6382+
bean can be used:
6383+
6384+
[source,java,indent=0]
6385+
----
6386+
include::{code-examples}/test/autoconfigure/restdocs/restassured/AdvancedConfigurationExample.java[tag=configuration]
6387+
----
6388+
6389+
6390+
63586391
[[boot-features-testing-spring-boot-applications-with-spock]]
63596392
==== Using Spock to test Spring Boot applications
63606393
If you wish to use Spock to test a Spring Boot application you should add a dependency
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.restdocs.restassured;
18+
19+
import org.springframework.boot.test.autoconfigure.restdocs.RestDocsRestAssuredConfigurationCustomizer;
20+
import org.springframework.boot.test.context.TestConfiguration;
21+
import org.springframework.restdocs.restassured3.RestAssuredRestDocumentationConfigurer;
22+
import org.springframework.restdocs.templates.TemplateFormats;
23+
24+
public class AdvancedConfigurationExample {
25+
26+
// tag::configuration[]
27+
@TestConfiguration
28+
public static class CustomizationConfiguration
29+
implements RestDocsRestAssuredConfigurationCustomizer {
30+
31+
@Override
32+
public void customize(RestAssuredRestDocumentationConfigurer configurer) {
33+
configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
34+
}
35+
36+
}
37+
// end::configuration[]
38+
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.test.autoconfigure.restdocs.restassured;
18+
19+
// tag::source[]
20+
import io.restassured.specification.RequestSpecification;
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
24+
import org.springframework.beans.factory.annotation.Autowired;
25+
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
26+
import org.springframework.boot.test.context.SpringBootTest;
27+
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
28+
import org.springframework.boot.web.server.LocalServerPort;
29+
import org.springframework.test.context.junit4.SpringRunner;
30+
31+
import static io.restassured.RestAssured.given;
32+
import static org.hamcrest.CoreMatchers.is;
33+
import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document;
34+
35+
@RunWith(SpringRunner.class)
36+
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
37+
@AutoConfigureRestDocs
38+
public class UserDocumentationTests {
39+
40+
@LocalServerPort
41+
private int port;
42+
43+
@Autowired
44+
private RequestSpecification documentationSpec;
45+
46+
@Test
47+
public void listUsers() throws Exception {
48+
given(this.documentationSpec).filter(document("list-users")).when()
49+
.port(this.port).get("/").then().assertThat().statusCode(is(200));
50+
}
51+
52+
}
53+
// end::source[]

spring-boot-parent/src/checkstyle/checkstyle.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
<module name="com.puppycrawl.tools.checkstyle.checks.imports.AvoidStarImportCheck" />
7171
<module name="com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheck">
7272
<property name="excludes"
73-
value="org.assertj.core.api.Assertions.*, org.junit.Assert.*, org.junit.Assume.*, org.junit.internal.matchers.ThrowableMessageMatcher.*, org.hamcrest.CoreMatchers.*, org.hamcrest.Matchers.*, org.springframework.boot.configurationprocessor.ConfigurationMetadataMatchers.*, org.springframework.boot.configurationprocessor.TestCompiler.*, org.springframework.boot.test.autoconfigure.AutoConfigurationImportedCondition.*, org.mockito.Mockito.*, org.mockito.BDDMockito.*, org.mockito.ArgumentMatchers.*, org.mockito.Matchers.*, org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*, org.springframework.restdocs.hypermedia.HypermediaDocumentation.*, org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*, org.springframework.test.web.servlet.result.MockMvcResultMatchers.*, org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*, org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*, org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo, org.springframework.test.web.client.ExpectedCount.*, org.springframework.test.web.client.match.MockRestRequestMatchers.*, org.springframework.test.web.client.response.MockRestResponseCreators.*" />
73+
value="io.restassured.RestAssured.*, org.assertj.core.api.Assertions.*, org.junit.Assert.*, org.junit.Assume.*, org.junit.internal.matchers.ThrowableMessageMatcher.*, org.hamcrest.CoreMatchers.*, org.hamcrest.Matchers.*, org.springframework.boot.configurationprocessor.ConfigurationMetadataMatchers.*, org.springframework.boot.configurationprocessor.TestCompiler.*, org.springframework.boot.test.autoconfigure.AutoConfigurationImportedCondition.*, org.mockito.Mockito.*, org.mockito.BDDMockito.*, org.mockito.ArgumentMatchers.*, org.mockito.Matchers.*, org.springframework.restdocs.hypermedia.HypermediaDocumentation.*, org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*, org.springframework.restdocs.operation.preprocess.Preprocessors.*, org.springframework.restdocs.restassured3.operation.preprocess.RestAssuredPreprocessors.*, org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.*, org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*, org.springframework.test.web.servlet.result.MockMvcResultMatchers.*, org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*, org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*, org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo, org.springframework.test.web.client.ExpectedCount.*, org.springframework.test.web.client.match.MockRestRequestMatchers.*, org.springframework.test.web.client.response.MockRestResponseCreators.*" />
7474
</module>
7575
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck" >
7676
<property name="illegalPkgs" value="com.google.common"/>

spring-boot-test-autoconfigure/pom.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@
5959
<artifactId>json-path</artifactId>
6060
<optional>true</optional>
6161
</dependency>
62+
<dependency>
63+
<groupId>io.rest-assured</groupId>
64+
<artifactId>rest-assured</artifactId>
65+
<optional>true</optional>
66+
</dependency>
6267
<dependency>
6368
<groupId>net.sourceforge.htmlunit</groupId>
6469
<artifactId>htmlunit</artifactId>
@@ -146,6 +151,11 @@
146151
<artifactId>spring-restdocs-mockmvc</artifactId>
147152
<optional>true</optional>
148153
</dependency>
154+
<dependency>
155+
<groupId>org.springframework.restdocs</groupId>
156+
<artifactId>spring-restdocs-restassured</artifactId>
157+
<optional>true</optional>
158+
</dependency>
149159
<dependency>
150160
<groupId>org.springframework.security</groupId>
151161
<artifactId>spring-security-config</artifactId>
@@ -198,6 +208,11 @@
198208
<artifactId>commons-pool2</artifactId>
199209
<scope>test</scope>
200210
</dependency>
211+
<dependency>
212+
<groupId>org.apache.tomcat.embed</groupId>
213+
<artifactId>tomcat-embed-core</artifactId>
214+
<optional>true</optional>
215+
</dependency>
201216
<dependency>
202217
<groupId>org.aspectj</groupId>
203218
<artifactId>aspectjrt</artifactId>

spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/restdocs/RestDocsAutoConfiguration.java

Lines changed: 63 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@
1616

1717
package org.springframework.boot.test.autoconfigure.restdocs;
1818

19+
import io.restassured.builder.RequestSpecBuilder;
20+
import io.restassured.specification.RequestSpecification;
21+
1922
import org.springframework.beans.factory.ObjectProvider;
2023
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
24+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2125
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2226
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
2327
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
@@ -29,40 +33,79 @@
2933
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
3034
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentationConfigurer;
3135
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
36+
import org.springframework.restdocs.restassured3.RestAssuredRestDocumentation;
37+
import org.springframework.restdocs.restassured3.RestAssuredRestDocumentationConfigurer;
3238

3339
/**
3440
* {@link EnableAutoConfiguration Auto-configuration} for Spring REST Docs.
3541
*
3642
* @author Andy Wilkinson
43+
* @author Eddú Meléndez
3744
* @since 1.4.0
3845
*/
3946
@Configuration
40-
@ConditionalOnWebApplication(type = Type.SERVLET)
4147
@EnableConfigurationProperties
48+
@ConditionalOnWebApplication
4249
public class RestDocsAutoConfiguration {
4350

44-
@Bean
45-
@ConditionalOnMissingBean(MockMvcRestDocumentationConfigurer.class)
46-
public MockMvcRestDocumentationConfigurer restDocsMockMvcConfigurer(
47-
ObjectProvider<RestDocsMockMvcConfigurationCustomizer> configurationCustomizerProvider,
48-
RestDocumentationContextProvider contextProvider) {
49-
MockMvcRestDocumentationConfigurer configurer = MockMvcRestDocumentation
50-
.documentationConfiguration(contextProvider);
51-
RestDocsMockMvcConfigurationCustomizer configurationCustomizer = configurationCustomizerProvider
52-
.getIfAvailable();
53-
if (configurationCustomizer != null) {
54-
configurationCustomizer.customize(configurer);
51+
@Configuration
52+
@ConditionalOnClass(MockMvcRestDocumentation.class)
53+
@ConditionalOnWebApplication(type = Type.SERVLET)
54+
static class RestDocsMockMvcAutoConfiguration {
55+
56+
@Bean
57+
@ConditionalOnMissingBean(MockMvcRestDocumentationConfigurer.class)
58+
public MockMvcRestDocumentationConfigurer restDocsMockMvcConfigurer(
59+
ObjectProvider<RestDocsMockMvcConfigurationCustomizer> configurationCustomizerProvider,
60+
RestDocumentationContextProvider contextProvider) {
61+
MockMvcRestDocumentationConfigurer configurer = MockMvcRestDocumentation
62+
.documentationConfiguration(contextProvider);
63+
RestDocsMockMvcConfigurationCustomizer configurationCustomizer = configurationCustomizerProvider
64+
.getIfAvailable();
65+
if (configurationCustomizer != null) {
66+
configurationCustomizer.customize(configurer);
67+
}
68+
return configurer;
5569
}
56-
return configurer;
70+
71+
@Bean
72+
@ConfigurationProperties(prefix = "spring.test.restdocs")
73+
public RestDocsMockMvcBuilderCustomizer restDocumentationConfigurer(
74+
MockMvcRestDocumentationConfigurer configurer,
75+
ObjectProvider<RestDocumentationResultHandler> resultHandler) {
76+
return new RestDocsMockMvcBuilderCustomizer(configurer,
77+
resultHandler.getIfAvailable());
78+
}
79+
5780
}
5881

59-
@Bean
60-
@ConfigurationProperties(prefix = "spring.test.restdocs")
61-
public RestDocsMockMvcBuilderCustomizer restDocumentationConfigurer(
62-
MockMvcRestDocumentationConfigurer configurer,
63-
ObjectProvider<RestDocumentationResultHandler> resultHandler) {
64-
return new RestDocsMockMvcBuilderCustomizer(configurer,
65-
resultHandler.getIfAvailable());
82+
@Configuration
83+
@ConditionalOnClass({ RequestSpecification.class,
84+
RestAssuredRestDocumentation.class })
85+
static class RestDocsRestAssuredAutoConfiguration {
86+
87+
@Bean
88+
@ConditionalOnMissingBean(RequestSpecification.class)
89+
public RequestSpecification restDocsRestAssuredConfigurer(
90+
ObjectProvider<RestDocsRestAssuredConfigurationCustomizer> configurationCustomizerProvider,
91+
RestDocumentationContextProvider contextProvider) {
92+
RestAssuredRestDocumentationConfigurer configurer = RestAssuredRestDocumentation
93+
.documentationConfiguration(contextProvider);
94+
RestDocsRestAssuredConfigurationCustomizer configurationCustomizer = configurationCustomizerProvider
95+
.getIfAvailable();
96+
if (configurationCustomizer != null) {
97+
configurationCustomizer.customize(configurer);
98+
}
99+
return new RequestSpecBuilder().addFilter(configurer).build();
100+
}
101+
102+
@Bean
103+
@ConfigurationProperties(prefix = "spring.test.restdocs")
104+
public RestDocsRestAssuredBuilderCustomizer restAssuredBuilderCustomizer(
105+
RequestSpecification configurer) {
106+
return new RestDocsRestAssuredBuilderCustomizer(configurer);
107+
}
108+
66109
}
67110

68111
}

0 commit comments

Comments
 (0)