Skip to content

Commit b304d85

Browse files
committed
Add support to RestDocs to work with ResAssured
See gh-7228
1 parent f2fe2c4 commit b304d85

File tree

9 files changed

+249
-4
lines changed

9 files changed

+249
-4
lines changed

spring-boot-dependencies/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
<quartz.version>2.3.0</quartz.version>
143143
<querydsl.version>4.1.4</querydsl.version>
144144
<reactor-bom.version>Bismuth-BUILD-SNAPSHOT</reactor-bom.version>
145+
<restassured.version>3.0.2</restassured.version>
145146
<rxjava.version>1.3.0</rxjava.version>
146147
<rxjava-adapter.version>1.2.1</rxjava-adapter.version>
147148
<rxjava2.version>2.1.0</rxjava2.version>
@@ -868,6 +869,11 @@
868869
<artifactId>rxjava</artifactId>
869870
<version>${rxjava2.version}</version>
870871
</dependency>
872+
<dependency>
873+
<groupId>io.rest-assured</groupId>
874+
<artifactId>rest-assured</artifactId>
875+
<version>${restassured.version}</version>
876+
</dependency>
871877
<dependency>
872878
<groupId>io.searchbox</groupId>
873879
<artifactId>jest</artifactId>

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.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.mockmvc.MockMvcRestDocumentation.*, org.springframework.restdocs.hypermedia.HypermediaDocumentation.*, org.springframework.restdocs.operation.preprocess.Preprocessors.*, org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.*, org.springframework.restdocs.restassured3.operation.preprocess.RestAssuredPreprocessors.*, 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.match.MockRestRequestMatchers.*, org.springframework.test.web.client.response.MockRestResponseCreators.*" />
7474
</module>
7575
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck" />
7676
<module name="com.puppycrawl.tools.checkstyle.checks.imports.RedundantImportCheck" />

spring-boot-test-autoconfigure/pom.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@
5454
<artifactId>json-path</artifactId>
5555
<optional>true</optional>
5656
</dependency>
57+
<dependency>
58+
<groupId>io.rest-assured</groupId>
59+
<artifactId>rest-assured</artifactId>
60+
<optional>true</optional>
61+
</dependency>
5762
<dependency>
5863
<groupId>net.sourceforge.htmlunit</groupId>
5964
<artifactId>htmlunit</artifactId>
@@ -141,6 +146,11 @@
141146
<artifactId>spring-restdocs-mockmvc</artifactId>
142147
<optional>true</optional>
143148
</dependency>
149+
<dependency>
150+
<groupId>org.springframework.restdocs</groupId>
151+
<artifactId>spring-restdocs-restassured</artifactId>
152+
<optional>true</optional>
153+
</dependency>
144154
<dependency>
145155
<groupId>org.springframework.security</groupId>
146156
<artifactId>spring-security-config</artifactId>
@@ -188,6 +198,11 @@
188198
<artifactId>commons-pool2</artifactId>
189199
<scope>test</scope>
190200
</dependency>
201+
<dependency>
202+
<groupId>org.apache.tomcat.embed</groupId>
203+
<artifactId>tomcat-embed-core</artifactId>
204+
<optional>true</optional>
205+
</dependency>
191206
<dependency>
192207
<groupId>org.aspectj</groupId>
193208
<artifactId>aspectjrt</artifactId>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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;
18+
19+
import io.restassured.builder.RequestSpecBuilder;
20+
import io.restassured.specification.RequestSpecification;
21+
22+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
23+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
24+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
25+
import org.springframework.boot.context.properties.ConfigurationProperties;
26+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
27+
import org.springframework.context.annotation.Bean;
28+
import org.springframework.context.annotation.Configuration;
29+
import org.springframework.restdocs.RestDocumentationContextProvider;
30+
import org.springframework.restdocs.restassured3.RestAssuredRestDocumentation;
31+
import org.springframework.restdocs.restassured3.RestAssuredRestDocumentationConfigurer;
32+
33+
/**
34+
* {@link EnableAutoConfiguration Auto-configuration} for Spring REST Docs with
35+
* RestAssured.
36+
*
37+
* @author Eddú Meléndez
38+
* @since 2.0.0
39+
*/
40+
@Configuration
41+
@ConditionalOnClass({ RequestSpecification.class, RestAssuredRestDocumentation.class })
42+
@EnableConfigurationProperties
43+
public class RestAssuredAutoConfiguration {
44+
45+
@Bean
46+
@ConditionalOnMissingBean(RequestSpecification.class)
47+
public RequestSpecification restDocsRestAssuredConfigurer(
48+
RestDocumentationContextProvider contextProvider) {
49+
RestAssuredRestDocumentationConfigurer configurer = RestAssuredRestDocumentation
50+
.documentationConfiguration(contextProvider);
51+
return new RequestSpecBuilder().addFilter(configurer).build();
52+
}
53+
54+
@Bean
55+
@ConfigurationProperties(prefix = "spring.test.restdocs")
56+
public RestDocsRestAssuredBuilderCustomizer restAssuredBuilderCustomizer(
57+
RequestSpecification configurer) {
58+
return new RestDocsRestAssuredBuilderCustomizer(configurer);
59+
}
60+
61+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.springframework.beans.factory.ObjectProvider;
2020
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
21+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2122
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2223
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
2324
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
@@ -34,10 +35,12 @@
3435
* {@link EnableAutoConfiguration Auto-configuration} for Spring REST Docs.
3536
*
3637
* @author Andy Wilkinson
38+
* @author Eddú Meléndez
3739
* @since 1.4.0
3840
*/
3941
@Configuration
4042
@ConditionalOnWebApplication(type = Type.SERVLET)
43+
@ConditionalOnClass(MockMvcRestDocumentation.class)
4144
@EnableConfigurationProperties
4245
public class RestDocsAutoConfiguration {
4346

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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;
18+
19+
import io.restassured.specification.RequestSpecification;
20+
21+
import org.springframework.beans.factory.InitializingBean;
22+
import org.springframework.util.StringUtils;
23+
24+
/**
25+
* A customizer that configures Spring REST Docs with RestAssured.
26+
*
27+
* @author Eddú Meléndez
28+
*/
29+
class RestDocsRestAssuredBuilderCustomizer implements InitializingBean {
30+
31+
private final RequestSpecification delegate;
32+
33+
private String uriScheme;
34+
35+
private String uriHost;
36+
37+
private Integer uriPort;
38+
39+
RestDocsRestAssuredBuilderCustomizer(RequestSpecification delegate) {
40+
this.delegate = delegate;
41+
}
42+
43+
public String getUriScheme() {
44+
return this.uriScheme;
45+
}
46+
47+
public void setUriScheme(String uriScheme) {
48+
this.uriScheme = uriScheme;
49+
}
50+
51+
public String getUriHost() {
52+
return this.uriHost;
53+
}
54+
55+
public void setUriHost(String uriHost) {
56+
this.uriHost = uriHost;
57+
}
58+
59+
public Integer getUriPort() {
60+
return this.uriPort;
61+
}
62+
63+
public void setUriPort(Integer uriPort) {
64+
this.uriPort = uriPort;
65+
}
66+
67+
@Override
68+
public void afterPropertiesSet() throws Exception {
69+
if (StringUtils.hasText(this.uriScheme) && StringUtils.hasText(this.uriHost)) {
70+
this.delegate.baseUri(this.uriScheme + "://" + this.uriHost);
71+
}
72+
if (this.uriPort != null) {
73+
this.delegate.port(this.uriPort);
74+
}
75+
}
76+
77+
}

spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerAuto
9898

9999
# AutoConfigureRestDocs auto-configuration imports
100100
org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs=\
101-
org.springframework.boot.test.autoconfigure.restdocs.RestDocsAutoConfiguration
101+
org.springframework.boot.test.autoconfigure.restdocs.RestDocsAutoConfiguration,\
102+
org.springframework.boot.test.autoconfigure.restdocs.RestAssuredAutoConfiguration
102103

103104
# AutoConfigureTestEntityManager auto-configuration imports
104105
org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureTestEntityManager=\
@@ -143,4 +144,4 @@ org.springframework.test.context.TestExecutionListener=\
143144
org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener,\
144145
org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener,\
145146
org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener,\
146-
org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener
147+
org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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;
18+
19+
import java.io.File;
20+
21+
import io.restassured.specification.RequestSpecification;
22+
import org.assertj.core.api.Condition;
23+
import org.junit.Before;
24+
import org.junit.Test;
25+
import org.junit.runner.RunWith;
26+
27+
import org.springframework.beans.factory.annotation.Autowired;
28+
import org.springframework.boot.test.context.SpringBootTest;
29+
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
30+
import org.springframework.boot.web.server.LocalServerPort;
31+
import org.springframework.test.context.junit4.SpringRunner;
32+
import org.springframework.util.FileSystemUtils;
33+
34+
import static io.restassured.RestAssured.given;
35+
import static org.assertj.core.api.Assertions.assertThat;
36+
import static org.hamcrest.CoreMatchers.is;
37+
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
38+
import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document;
39+
import static org.springframework.restdocs.restassured3.operation.preprocess.RestAssuredPreprocessors.modifyUris;
40+
41+
/**
42+
* Tests for {@link RestAssuredAutoConfiguration}
43+
*
44+
* @author Eddú Meléndez
45+
*/
46+
@RunWith(SpringRunner.class)
47+
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
48+
@AutoConfigureRestDocs
49+
public class RestAssuredAutoConfigurationIntegrationTests {
50+
51+
@LocalServerPort
52+
private int port;
53+
54+
@Before
55+
public void deleteSnippets() {
56+
FileSystemUtils.deleteRecursively(new File("target/generated-snippets"));
57+
}
58+
59+
@Autowired
60+
private RequestSpecification documentationSpec;
61+
62+
@Test
63+
public void defaultSnippetsAreWritten() throws Exception {
64+
given(this.documentationSpec)
65+
.filter(document("default-snippets", preprocessRequest(modifyUris()
66+
.scheme("https").host("api.example.com").removePort()))).when()
67+
.port(this.port).get("/").then().assertThat().statusCode(is(200));
68+
File defaultSnippetsDir = new File("target/generated-snippets/default-snippets");
69+
assertThat(defaultSnippetsDir).exists();
70+
assertThat(new File(defaultSnippetsDir, "curl-request.adoc")).has(
71+
contentContaining("'https://api.example.com/'"));
72+
assertThat(new File(defaultSnippetsDir, "http-request.adoc")).has(
73+
contentContaining("api.example.com"));
74+
assertThat(new File(defaultSnippetsDir, "http-response.adoc")).isFile();
75+
}
76+
77+
private Condition<File> contentContaining(String toContain) {
78+
return new ContentContainingCondition(toContain);
79+
}
80+
81+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@
1717
package org.springframework.boot.test.autoconfigure.restdocs;
1818

1919
import org.springframework.boot.autoconfigure.SpringBootApplication;
20+
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
2021

2122
/**
2223
* Test application used with {@link AutoConfigureRestDocs} tests.
2324
*
2425
* @author Andy Wilkinson
2526
*/
26-
@SpringBootApplication
27+
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
2728
public class RestDocsTestApplication {
2829

2930
}

0 commit comments

Comments
 (0)