Restore support for REST Assured

Closes gh-784
This commit is contained in:
Andy Wilkinson
2022-01-21 15:33:21 +00:00
parent f5beaaacff
commit d38d79755b
53 changed files with 3403 additions and 11 deletions

View File

@@ -45,6 +45,17 @@ TIP: To configure a request's context path, use the `contextPath` method on `Moc
[[configuration-uris-rest-assured]]
==== REST Assured URI Customization
REST Assured tests a service by making actual HTTP requests. As a result, URIs must be
customized once the operation on the service has been performed but before it is
documented. A
<<customizing-requests-and-responses-preprocessors-modify-uris, REST-Assured-specific
preprocessor>> is provided for this purpose.
[[configuration-uris-webtestclient]]
==== WebTestClient URI Customization
@@ -79,6 +90,12 @@ include::{examples-dir}/com/example/mockmvc/CustomEncoding.java[tags=custom-enco
include::{examples-dir}/com/example/webtestclient/CustomEncoding.java[tags=custom-encoding]
----
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/CustomEncoding.java[tags=custom-encoding]
----
TIP: When Spring REST Docs converts the content of a request or a response to a `String`, the `charset` specified in the `Content-Type` header is used if it is available.
In its absence, the JVM's default `Charset` is used.
You can configure the JVM's default `Charset` by using the `file.encoding` system property.
@@ -105,6 +122,13 @@ include::{examples-dir}/com/example/mockmvc/CustomFormat.java[tags=custom-format
include::{examples-dir}/com/example/webtestclient/CustomFormat.java[tags=custom-format]
----
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/CustomFormat.java[tags=custom-format]
----
====
[[configuration-default-snippets]]
@@ -134,6 +158,12 @@ include::{examples-dir}/com/example/mockmvc/CustomDefaultSnippets.java[tags=cust
include::{examples-dir}/com/example/webtestclient/CustomDefaultSnippets.java[tags=custom-default-snippets]
----
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/CustomDefaultSnippets.java[tags=custom-default-snippets]
----
[[configuration-default-preprocessors]]
@@ -158,4 +188,10 @@ include::{examples-dir}/com/example/webtestclient/CustomDefaultOperationPreproce
<1> Apply a request preprocessor that removes the header named `Foo`.
<2> Apply a response preprocessor that pretty prints its content.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/CustomDefaultOperationPreprocessors.java[tags=custom-default-operation-preprocessors]
----
<1> Apply a request preprocessor that removes the header named `Foo`.
<2> Apply a response preprocessor that pretty prints its content.

View File

@@ -24,6 +24,14 @@ include::{examples-dir}/com/example/webtestclient/PerTestPreprocessing.java[tags
<1> Apply a request preprocessor that removes the header named `Foo`.
<2> Apply a response preprocessor that pretty prints its content.
.REST Assured
----
include::{examples-dir}/com/example/restassured/PerTestPreprocessing.java[tags=preprocessing]
----
<1> Apply a request preprocessor that removes the header named `Foo`.
<2> Apply a response preprocessor that pretty prints its content.
====
Alternatively, you may want to apply the same preprocessors to every test.
You can do so by using the `RestDocumentationConfigurer` API in your `@Before` method to configure the preprocessors.
For example, to remove the `Foo` header from all requests and pretty print all responses, you could do one of the following (depending on your testing environment):
@@ -44,6 +52,14 @@ include::{examples-dir}/com/example/webtestclient/EveryTestPreprocessing.java[ta
<1> Apply a request preprocessor that removes the header named `Foo`.
<2> Apply a response preprocessor that pretty prints its content.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/EveryTestPreprocessing.java[tags=setup]
----
<1> Apply a request preprocessor that removes the header named `Foo`.
<2> Apply a response preprocessor that pretty prints its content.
Then, in each test, you can perform any configuration specific to that test.
The following examples show how to do so:
@@ -59,6 +75,12 @@ include::{examples-dir}/com/example/mockmvc/EveryTestPreprocessing.java[tags=use
include::{examples-dir}/com/example/webtestclient/EveryTestPreprocessing.java[tags=use]
----
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/EveryTestPreprocessing.java[tags=use]
----
Various built-in preprocessors, including those illustrated above, are available through the static methods on `Preprocessors`.
See <<Preprocessors, below>> for further details.
@@ -116,7 +138,7 @@ You can use `modifyParameters` on `Preprocessors` to add, set, and remove reques
TIP: If you use MockMvc or a WebTestClient that is not bound to a server, you should customize URIs by <<configuration-uris, changing the configuration>>.
You can use `modifyUris` on `Preprocessors` to modify any URIs in a request or a response.
When using WebTestClient bound to a server, this lets you customize the URIs that appear in the documentation while testing a local instance of the service.
When using REST Assured or WebTestClient bound to a server, this lets you customize the URIs that appear in the documentation while testing a local instance of the service.

View File

@@ -33,6 +33,18 @@ Uses the static `links` method on `org.springframework.restdocs.hypermedia.Hyper
Uses the static `linkWithRel` method on `org.springframework.restdocs.hypermedia.HypermediaDocumentation`.
<3> Expect a link whose `rel` is `bravo`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/Hypermedia.java[tag=links]
----
<1> Configure Spring REST docs to produce a snippet describing the response's links.
Uses the static `links` method on
`org.springframework.restdocs.hypermedia.HypermediaDocumentation`.
<2> Expect a link whose `rel` is `alpha`. Uses the static `linkWithRel` method on
`org.springframework.restdocs.hypermedia.HypermediaDocumentation`.
<3> Expect a link whose `rel` is `bravo`.
The result is a snippet named `links.adoc` that contains a table describing the resource's links.
TIP: If a link in the response has a `title`, you can omit the description from its descriptor and the `title` is used.
@@ -79,6 +91,14 @@ include::{examples-dir}/com/example/webtestclient/Hypermedia.java[tag=explicit-e
<1> Indicate that the links are in HAL format.
Uses the static `halLinks` method on `org.springframework.restdocs.hypermedia.HypermediaDocumentation`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/Hypermedia.java[tag=explicit-extractor]
----
<1> Indicate that the links are in HAL format. Uses the static `halLinks` method on
`org.springframework.restdocs.hypermedia.HypermediaDocumentation`.
If your API represents its links in a format other than Atom or HAL, you can provide your own implementation of the `LinkExtractor` interface to extract the links from the response.
@@ -150,6 +170,18 @@ Both are static methods on `org.springframework.restdocs.payload.PayloadDocument
Uses the static `fieldWithPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`.
<3> Expect a field with the path `contact.name`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/Payload.java[tags=response]
----
<1> Configure Spring REST docs to produce a snippet describing the fields in the response payload.
To document a request, you can use `requestFields`.
Both are static methods on `org.springframework.restdocs.payload.PayloadDocumentation`.
<2> Expect a field with the path `contact.email`.
Uses the static `fieldWithPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`.
<3> Expect a field with the path `contact.name`.
The result is a snippet that contains a table describing the fields.
For requests, this snippet is named `request-fields.adoc`.
For responses, this snippet is named `response-fields.adoc`.
@@ -178,6 +210,14 @@ include::{examples-dir}/com/example/webtestclient/Payload.java[tags=subsection]
`contact.email` and `contact.name` are now seen as having also been documented.
Uses the static `subsectionWithPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/Payload.java[tags=subsection]
----
<1> Document the subsection with the path `contact`. `contact.email` and `contact.name` are now seen as having also been documented.
Uses the static `subsectionWithPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`.
`subsectionWithPath` can be useful for providing a high-level overview of a particular section of a payload.
You can then produce separate, more detailed documentation for a subsection.
See <<documenting-your-api-request-response-payloads-subsections>>.
@@ -357,6 +397,13 @@ include::{examples-dir}/com/example/webtestclient/Payload.java[tags=explicit-typ
----
<1> Set the field's type to `String`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/Payload.java[tags=explicit-type]
----
<1> Set the field's type to `String`.
[[documenting-your-api-request-response-payloads-fields-xml]]
@@ -440,6 +487,13 @@ include::{examples-dir}/com/example/webtestclient/Payload.java[tags=single-book]
----
<1> Document `title` and `author` by using existing descriptors
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/Payload.java[tags=single-book]
----
<1> Document `title` and `author` by using existing descriptors
You can also use the descriptors to document an array of books, as follows:
[source,java,indent=0,role="primary"]
@@ -460,6 +514,16 @@ include::{examples-dir}/com/example/webtestclient/Payload.java[tags=book-array]
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/Payload.java[tags=book-array]
----
<1> Document the array.
<2> Document `[].title` and `[].author` by using the existing descriptors prefixed with `[].`
[[documenting-your-api-request-response-payloads-subsections]]
==== Documenting a Subsection of a Request or Response Payload
@@ -509,6 +573,15 @@ include::{examples-dir}/com/example/webtestclient/Payload.java[tags=body-subsect
Uses the static `responseBody` and `beneathPath` methods on `org.springframework.restdocs.payload.PayloadDocumentation`.
To produce a snippet for the request body, you can use `requestBody` in place of `responseBody`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/Payload.java[tags=body-subsection]
----
<1> Produce a snippet containing a subsection of the response body.
Uses the static `responseBody` and `beneathPath` methods on `org.springframework.restdocs.payload.PayloadDocumentation`.
To produce a snippet for the request body, you can use `requestBody` in place of `responseBody`.
The result is a snippet with the following contents:
[source,json,indent=0]
@@ -559,6 +632,16 @@ include::{examples-dir}/com/example/webtestclient/Payload.java[tags=fields-subse
Uses the static `beneathPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`.
<2> Document the `high` and `low` fields.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/Payload.java[tags=fields-subsection]
----
<1> Produce a snippet describing the fields in the subsection of the response payload
beneath the path `weather.temperature`. Uses the static `beneathPath` method on
`org.springframework.restdocs.payload.PayloadDocumentation`.
<2> Document the `high` and `low` fields.
The result is a snippet that contains a table describing the `high` and `low` fields of `weather.temperature`.
To make the snippet's name distinct, an identifier for the subsection is included.
By default, this identifier is `beneath-${path}`.
@@ -597,6 +680,18 @@ Uses the static `requestParameters` method on `org.springframework.restdocs.requ
Uses the static `parameterWithName` method on `org.springframework.restdocs.request.RequestDocumentation`.
<4> Document the `per_page` parameter.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/RequestParameters.java[tags=request-parameters-query-string]
----
<1> Configure Spring REST Docs to produce a snippet describing the request's parameters.
Uses the static `requestParameters` method on `org.springframework.restdocs.request.RequestDocumentation`.
<2> Document the `page` parameter.
Uses the static `parameterWithName` method on `org.springframework.restdocs.request.RequestDocumentation`.
<3> Document the `per_page` parameter.
<4> Perform a `GET` request with two parameters, `page` and `per_page`, in the query string.
You can also include request parameters as form data in the body of a POST request.
The following examples show how to do so:
@@ -614,6 +709,14 @@ include::{examples-dir}/com/example/webtestclient/RequestParameters.java[tags=re
----
<1> Perform a `POST` request with a single parameter, `username`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/RequestParameters.java[tags=request-parameters-form-data]
----
<1> Configure the `username` parameter.
<2> Perform the `POST` request.
In all cases, the result is a snippet named `request-parameters.adoc` that contains a table describing the parameters that are supported by the resource.
When documenting request parameters, the test fails if an undocumented request parameter is used in the request.
@@ -658,6 +761,18 @@ Uses the static `pathParameters` method on `org.springframework.restdocs.request
Uses the static `parameterWithName` method on `org.springframework.restdocs.request.RequestDocumentation`.
<4> Document the parameter named `longitude`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/PathParameters.java[tags=path-parameters]
----
<1> Configure Spring REST Docs to produce a snippet describing the request's path parameters.
Uses the static `pathParameters` method on `org.springframework.restdocs.request.RequestDocumentation`.
<2> Document the parameter named `latitude`.
Uses the static `parameterWithName` method on `org.springframework.restdocs.request.RequestDocumentation`.
<3> Document the parameter named `longitude`.
<4> Perform a `GET` request with two path parameters, `latitude` and `longitude`.
The result is a snippet named `path-parameters.adoc` that contains a table describing the path parameters that are supported by the resource.
TIP: If you use MockMvc, to make the path parameters available for documentation, you must build the request by using one of the methods on `RestDocumentationRequestBuilders` rather than `MockMvcRequestBuilders`.
@@ -702,6 +817,17 @@ Uses the static `requestParts` method on `org.springframework.restdocs.request.R
<3> Document the part named `file`.
Uses the static `partWithName` method on `org.springframework.restdocs.request.RequestDocumentation`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/RequestParts.java[tags=request-parts]
----
<1> Configure Spring REST Docs to produce a snippet describing the request's parts.
Uses the static `requestParts` method on `org.springframework.restdocs.request.RequestDocumentation`.
<2> Document the part named `file`. Uses the static `partWithName` method on `org.springframework.restdocs.request.RequestDocumentation`.
<3> Configure the request with the part named `file`.
<4> Perform the `POST` request to `/upload`.
The result is a snippet named `request-parts.adoc` that contains a table describing the request parts that are supported by the resource.
When documenting request parts, the test fails if an undocumented part is used in the request.
@@ -744,6 +870,14 @@ include::{examples-dir}/com/example/webtestclient/RequestPartPayload.java[tags=b
<1> Configure Spring REST docs to produce a snippet containing the body of the request part named `metadata`.
Uses the static `requestPartBody` method on `PayloadDocumentation`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/RequestPartPayload.java[tags=body]
----
<1> Configure Spring REST docs to produce a snippet containing the body of the request part named `metadata`.
Uses the static `requestPartBody` method on `PayloadDocumentation`.
The result is a snippet named `request-part-${part-name}-body.adoc` that contains the part's body.
For example, documenting a part named `metadata` produces a snippet named `request-part-metadata-body.adoc`.
@@ -774,6 +908,16 @@ Uses the static `requestPartFields` method on `PayloadDocumentation`.
<2> Expect a field with the path `version`.
Uses the static `fieldWithPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/RequestPartPayload.java[tags=fields]
----
<1> Configure Spring REST docs to produce a snippet describing the fields in the payload of the request part named `metadata`.
Uses the static `requestPartFields` method on `PayloadDocumentation`.
<2> Expect a field with the path `version`.
Uses the static `fieldWithPath` method on `org.springframework.restdocs.payload.PayloadDocumentation`.
The result is a snippet that contains a table describing the part's fields.
This snippet is named `request-part-${part-name}-fields.adoc`.
For example, documenting a part named `metadata` produces a snippet named `request-part-metadata-fields.adoc`.
@@ -825,6 +969,19 @@ Uses the static `headerWithName` method on `org.springframework.restdocs.headers
<4> Produce a snippet describing the response's headers.
Uses the static `responseHeaders` method on `org.springframework.restdocs.headers.HeaderDocumentation`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/HttpHeaders.java[tags=headers]
----
<1> Configure Spring REST Docs to produce a snippet describing the request's headers.
Uses the static `requestHeaders` method on `org.springframework.restdocs.headers.HeaderDocumentation`.
<2> Document the `Authorization` header.
Uses the static `headerWithName` method on `org.springframework.restdocs.headers.HeaderDocumentation.
<3> Produce a snippet describing the response's headers.
Uses the static `responseHeaders` method on `org.springframework.restdocs.headers.HeaderDocumentation`.
<4> Configure the request with an `Authorization` header that uses basic authentication.
The result is a snippet named `request-headers.adoc` and a snippet named `response-headers.adoc`.
Each contains a table describing the headers.
@@ -863,6 +1020,13 @@ include::{examples-dir}/com/example/webtestclient/WebTestClientSnippetReuse.java
----
<1> Reuse the `pagingLinks` `Snippet`, calling `and` to add descriptors that are specific to the resource that is being documented.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/RestAssuredSnippetReuse.java[tags=use]
----
<1> Reuse the `pagingLinks` `Snippet`, calling `and` to add descriptors that are specific to the resource that is being documented.
The result of the example is that links with `rel` values of `first`, `last`, `next`, `previous`, `alpha`, and `bravo` are all documented.
@@ -1045,6 +1209,12 @@ The following examples show how to do so:
include::{examples-dir}/com/example/mockmvc/ParameterizedOutput.java[tags=parameterized-output]
----
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/ParameterizedOutput.java[tags=parameterized-output]
----
[source,java,indent=0,role="secondary"]
.WebTestClient
----
@@ -1112,8 +1282,16 @@ include::{examples-dir}/com/example/webtestclient/Payload.java[tags=constraints]
<2> Set the `constraints` attribute for the `name` field.
<3> Set the `constraints` attribute for the `email` field.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/Payload.java[tags=constraints]
----
<1> Configure the `title` attribute for the request fields snippet.
<2> Set the `constraints` attribute for the `name` field.
<3> Set the `constraints` attribute for the `email` field.
The second step is to provide a custom template named `request-fields.snippet` that includes the information about the fields' constraints in the generated snippet's table and adds a title.
The following example shows how to do so:
[source,indent=0]
----

View File

@@ -34,6 +34,19 @@ If you want to jump straight in, a number of sample applications are available:
| Demonstrates the use of Spring REST docs with Spring WebFlux's WebTestClient.
|===
[cols="3,2,10"]
.REST Assured
|===
| Sample | Build system | Description
| {samples}/rest-assured[REST Assured]
| Gradle
| Demonstrates the use of Spring REST Docs with http://rest-assured.io[REST Assured].
|===
[cols="3,2,10"]
.Advanced
|===
@@ -63,7 +76,7 @@ Spring REST Docs has the following minimum requirements:
* Java 17
* Spring Framework 6
Additionally, the `spring-restdocs-restassured` module requires REST Assured 4 (4.5 or later).
[[getting-started-build-configuration]]
=== Build configuration
@@ -113,7 +126,7 @@ The key parts of the configuration are described in the following listings:
</build>
----
<1> Add a dependency on `spring-restdocs-mockmvc` in the `test` scope.
If you want to use `WebTestClient` add a dependency on `spring-restdocs-webtestclient` instead.
If you want to use `WebTestClient` or REST Assured rather than MockMvc, add a dependency on `spring-restdocs-webtestclient` or `spring-restdocs-restassured` respectively instead.
<2> Add the Asciidoctor plugin.
<3> Using `prepare-package` allows the documentation to be <<getting-started-build-configuration-packaging-the-documentation, included in the package>>.
<4> Add `spring-restdocs-asciidoctor` as a dependency of the Asciidoctor plugin.
@@ -156,7 +169,7 @@ It will also allow you to use the `operation` block macro.
This will automatically configure the `snippets` attribute for use in your `.adoc` files to point to `build/generated-snippets`.
It will also allow you to use the `operation` block macro.
<4> Add a dependency on `spring-restdocs-mockmvc` in the `testImplementation` configuration.
If you want to use `WebTestClient`, add a dependency on `spring-restdocs-webtestclient` instead.
If you want to use `WebTestClient` or REST Assured rather than MockMvc, add a dependency on `spring-restdocs-webtestclient` or `spring-restdocs-restassured` respectively instead.
<5> Configure a property to define the output location for generated snippets.
<6> Configure the `test` task to add the snippets directory as an output.
<7> Configure the `asciidoctor` task.
@@ -232,7 +245,7 @@ The following listings show how to do so in both Maven and Gradle:
[[getting-started-documentation-snippets]]
=== Generating Documentation Snippets
Spring REST Docs uses Spring MVC's {spring-framework-docs}/testing.html#spring-mvc-test-framework[test framework] or Spring WebFlux's {spring-framework-docs}/testing.html#webtestclient[`WebTestClient`] to make requests to the service that you are documenting.
Spring REST Docs uses Spring MVC's {spring-framework-docs}/testing.html#spring-mvc-test-framework[test framework] or Spring WebFlux's {spring-framework-docs}/testing.html#webtestclient[`WebTestClient`], or https://rest-assured.io[REST Assured] to make requests to the service that you are documenting.
It then produces documentation snippets for the request and the resulting response.
@@ -280,7 +293,7 @@ The following example shows how to do so:
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("custom");
----
Next, you must provide an `@Before` method to configure MockMvc or WebTestClient.
Next, you must provide an `@Before` method to configure MockMvc or WebTestClient, or REST Assured.
The following examples show how to do so:
[source,java,indent=0,role="primary"]
@@ -299,6 +312,14 @@ include::{examples-dir}/com/example/webtestclient/ExampleApplicationTests.java[t
<1> The `WebTestClient` instance is configured by adding a `WebTestclientRestDocumentationConfigurer` as an `ExchangeFilterFunction`.
You can obtain an instance of this class from the static `documentationConfiguration()` method on `org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/ExampleApplicationTests.java[tags=setup]
----
<1> REST Assured is configured by adding a `RestAssuredRestDocumentationConfigurer` as a `Filter`.
You can obtain an instance of this class from the static `documentationConfiguration()` method on `RestAssuredRestDocumentation` in the `org.springframework.restdocs.restassured` package.
The configurer applies sensible defaults and also provides an API for customizing the configuration.
See the <<configuration, configuration section>> for more information.
@@ -350,7 +371,7 @@ public class JUnit5ExampleTests {
}
----
Next, you must provide a `@BeforeEach` method to configure MockMvc or WebTestClient.
Next, you must provide a `@BeforeEach` method to configure MockMvc or WebTestClient, or REST Assured.
The following listings show how to do so:
[source,java,indent=0,role="primary"]
@@ -369,6 +390,14 @@ include::{examples-dir}/com/example/webtestclient/ExampleApplicationJUnit5Tests.
<1> The `WebTestClient` instance is configured by adding a `WebTestClientRestDocumentationConfigurer` as an `ExchangeFilterFunction`.
You can obtain an instance of this class from the static `documentationConfiguration()` method on `org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/ExampleApplicationJUnit5Tests.java[tags=setup]
----
<1> REST Assured is configured by adding a `RestAssuredRestDocumentationConfigurer` as a `Filter`.
You can obtain an instance of this class from the static `documentationConfiguration()` method on `RestAssuredRestDocumentation` in the `org.springframework.restdocs.restassured` package.
The configurer applies sensible defaults and also provides an API for customizing the configuration.
See the <<configuration, configuration section>> for more information.
@@ -391,7 +420,7 @@ private ManualRestDocumentation restDocumentation = new ManualRestDocumentation(
----
Secondly, you must call `ManualRestDocumentation.beforeTest(Class, String)` before each test.
You can do so as part of the method that configures MockMvc or WebTestClient.
You can do so as part of the method that configures MockMvc, WebTestClient, or REST Assured.
The following examples show how to do so:
[source,java,indent=0,role="primary"]
@@ -406,6 +435,12 @@ include::{examples-dir}/com/example/mockmvc/ExampleApplicationTestNgTests.java[t
include::{examples-dir}/com/example/webtestclient/ExampleApplicationTestNgTests.java[tags=setup]
----
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/ExampleApplicationTestNgTests.java[tags=setup]
----
Finally, you must call `ManualRestDocumentation.afterTest` after each test.
The following example shows how to do so with TestNG:
@@ -444,6 +479,19 @@ include::{examples-dir}/com/example/webtestclient/InvokeService.java[tags=invoke
The snippets are written by a `Consumer` of the `ExchangeResult`.
You can obtain such a consumer from the static `document` method on `org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation`.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/InvokeService.java[tags=invoke-service]
----
<1> Apply the specification that was initialized in the `@Before` method.
<2> Indicate that an `application/json` response is required.
<3> Document the call to the service, writing the snippets into a directory named `index` (which is located beneath the configured output directory).
The snippets are written by a `RestDocumentationFilter`.
You can obtain an instance of this class from the static `document` method on `RestAssuredRestDocumentation` in the `org.springframework.restdocs.restassured` package.
<4> Invoke the root (`/`) of the service.
<5> Assert that the service produce the expected response.
By default, six snippets are written:
* `<output-directory>/index/curl-request.adoc`

View File

@@ -9,7 +9,7 @@ To this end, Spring REST Docs uses https://asciidoctor.org[Asciidoctor] by defau
Asciidoctor processes plain text and produces HTML, styled and laid out to suit your needs.
If you prefer, you can also configure Spring REST Docs to use Markdown.
Spring REST Docs uses snippets produced by tests written with Spring MVC's {spring-framework-docs}/testing.html#spring-mvc-test-framework[test framework] or Spring WebFlux's {spring-framework-docs}/testing.html#webtestclient[`WebTestClient`].
Spring REST Docs uses snippets produced by tests written with Spring MVC's {spring-framework-docs}/testing.html#spring-mvc-test-framework[test framework], Spring WebFlux's {spring-framework-docs}/testing.html#webtestclient[`WebTestClient`] or http://rest-assured.io[REST Assured 4].
This test-driven approach helps to guarantee the accuracy of your service's documentation.
If a snippet is incorrect, the test that produces it fails.

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.JUnitRestDocumentation;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.removeHeaders;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
public class CustomDefaultOperationPreprocessors {
@Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();
@SuppressWarnings("unused")
private RequestSpecification spec;
@Before
public void setup() {
// tag::custom-default-operation-preprocessors[]
this.spec = new RequestSpecBuilder()
.addFilter(documentationConfiguration(this.restDocumentation).operationPreprocessors()
.withRequestDefaults(removeHeaders("Foo")) // <1>
.withResponseDefaults(prettyPrint())) // <2>
.build();
// end::custom-default-operation-preprocessors[]
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.JUnitRestDocumentation;
import static org.springframework.restdocs.cli.CliDocumentation.curlRequest;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
public class CustomDefaultSnippets {
@Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();
@SuppressWarnings("unused")
private RequestSpecification spec;
@Before
public void setUp() {
// tag::custom-default-snippets[]
this.spec = new RequestSpecBuilder()
.addFilter(documentationConfiguration(this.restDocumentation).snippets().withDefaults(curlRequest()))
.build();
// end::custom-default-snippets[]
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.JUnitRestDocumentation;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
public class CustomEncoding {
@Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();
@SuppressWarnings("unused")
private RequestSpecification spec;
@Before
public void setUp() {
// tag::custom-encoding[]
this.spec = new RequestSpecBuilder()
.addFilter(documentationConfiguration(this.restDocumentation).snippets().withEncoding("ISO-8859-1"))
.build();
// end::custom-encoding[]
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.JUnitRestDocumentation;
import org.springframework.restdocs.templates.TemplateFormats;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
public class CustomFormat {
@Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();
@SuppressWarnings("unused")
private RequestSpecification spec;
@Before
public void setUp() {
// tag::custom-format[]
this.spec = new RequestSpecBuilder().addFilter(documentationConfiguration(this.restDocumentation).snippets()
.withTemplateFormat(TemplateFormats.markdown())).build();
// end::custom-format[]
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.RestAssured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.JUnitRestDocumentation;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel;
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.removeHeaders;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
public class EveryTestPreprocessing {
@Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();
// tag::setup[]
private RequestSpecification spec;
@Before
public void setup() {
this.spec = new RequestSpecBuilder()
.addFilter(documentationConfiguration(this.restDocumentation).operationPreprocessors()
.withRequestDefaults(removeHeaders("Foo")) // <1>
.withResponseDefaults(prettyPrint())) // <2>
.build();
}
// end::setup[]
public void use() throws Exception {
// tag::use[]
RestAssured.given(this.spec)
.filter(document("index", links(linkWithRel("self").description("Canonical self link")))).when()
.get("/").then().assertThat().statusCode(is(200));
// end::use[]
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.restdocs.RestDocumentationContextProvider;
import org.springframework.restdocs.RestDocumentationExtension;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
@ExtendWith(RestDocumentationExtension.class)
public class ExampleApplicationJUnit5Tests {
@SuppressWarnings("unused")
// tag::setup[]
private RequestSpecification spec;
@BeforeEach
public void setUp(RestDocumentationContextProvider restDocumentation) {
this.spec = new RequestSpecBuilder().addFilter(documentationConfiguration(restDocumentation)) // <1>
.build();
}
// end::setup[]
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import java.lang.reflect.Method;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.springframework.restdocs.ManualRestDocumentation;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
public class ExampleApplicationTestNgTests {
private final ManualRestDocumentation restDocumentation = new ManualRestDocumentation();
@SuppressWarnings("unused")
// tag::setup[]
private RequestSpecification spec;
@BeforeMethod
public void setUp(Method method) {
this.spec = new RequestSpecBuilder().addFilter(documentationConfiguration(this.restDocumentation)).build();
this.restDocumentation.beforeTest(getClass(), method.getName());
}
// end::setup[]
// tag::teardown[]
@AfterMethod
public void tearDown() {
this.restDocumentation.afterTest();
}
// end::teardown[]
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.JUnitRestDocumentation;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
public class ExampleApplicationTests {
@Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();
@SuppressWarnings("unused")
// tag::setup[]
private RequestSpecification spec;
@Before
public void setUp() {
this.spec = new RequestSpecBuilder().addFilter(documentationConfiguration(this.restDocumentation)) // <1>
.build();
}
// end::setup[]
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.RestAssured;
import io.restassured.specification.RequestSpecification;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders;
import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
public class HttpHeaders {
private RequestSpecification spec;
public void headers() throws Exception {
// tag::headers[]
RestAssured.given(this.spec).filter(document("headers", requestHeaders(// <1>
headerWithName("Authorization").description("Basic auth credentials")), // <2>
responseHeaders(// <3>
headerWithName("X-RateLimit-Limit")
.description("The total number of requests permitted per period"),
headerWithName("X-RateLimit-Remaining")
.description("Remaining requests permitted in current period"),
headerWithName("X-RateLimit-Reset")
.description("Time at which the rate limit period will reset"))))
.header("Authorization", "Basic dXNlcjpzZWNyZXQ=") // <4>
.when().get("/people").then().assertThat().statusCode(is(200));
// end::headers[]
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.RestAssured;
import io.restassured.specification.RequestSpecification;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.halLinks;
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel;
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
public class Hypermedia {
private RequestSpecification spec;
public void defaultExtractor() throws Exception {
// tag::links[]
RestAssured.given(this.spec).accept("application/json").filter(document("index", links(// <1>
linkWithRel("alpha").description("Link to the alpha resource"), // <2>
linkWithRel("bravo").description("Link to the bravo resource")))) // <3>
.get("/").then().assertThat().statusCode(is(200));
// end::links[]
}
public void explicitExtractor() throws Exception {
RestAssured.given(this.spec).accept("application/json")
// tag::explicit-extractor[]
.filter(document("index", links(halLinks(), // <1>
linkWithRel("alpha").description("Link to the alpha resource"),
linkWithRel("bravo").description("Link to the bravo resource"))))
// end::explicit-extractor[]
.get("/").then().assertThat().statusCode(is(200));
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.RestAssured;
import io.restassured.specification.RequestSpecification;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
public class InvokeService {
private RequestSpecification spec;
public void invokeService() throws Exception {
// tag::invoke-service[]
RestAssured.given(this.spec) // <1>
.accept("application/json") // <2>
.filter(document("index")) // <3>
.when().get("/") // <4>
.then().assertThat().statusCode(is(200)); // <5>
// end::invoke-service[]
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.JUnitRestDocumentation;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
public class ParameterizedOutput {
@Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();
@SuppressWarnings("unused")
private RequestSpecification spec;
// tag::parameterized-output[]
@Before
public void setUp() {
this.spec = new RequestSpecBuilder().addFilter(documentationConfiguration(this.restDocumentation))
.addFilter(document("{method-name}/{step}")).build();
}
// end::parameterized-output[]
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.RestAssured;
import io.restassured.specification.RequestSpecification;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
public class PathParameters {
private RequestSpecification spec;
public void pathParametersSnippet() throws Exception {
// tag::path-parameters[]
RestAssured.given(this.spec).filter(document("locations", pathParameters(// <1>
parameterWithName("latitude").description("The location's latitude"), // <2>
parameterWithName("longitude").description("The location's longitude")))) // <3>
.when().get("/locations/{latitude}/{longitude}", 51.5072, 0.1275) // <4>
.then().assertThat().statusCode(is(200));
// end::path-parameters[]
}
}

View File

@@ -0,0 +1,115 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.RestAssured;
import io.restassured.specification.RequestSpecification;
import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.restdocs.payload.JsonFieldType;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.payload.PayloadDocumentation.beneathPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseBody;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
import static org.springframework.restdocs.snippet.Attributes.attributes;
import static org.springframework.restdocs.snippet.Attributes.key;
public class Payload {
private RequestSpecification spec;
public void response() throws Exception {
// tag::response[]
RestAssured.given(this.spec).accept("application/json").filter(document("user", responseFields(// <1>
fieldWithPath("contact.name").description("The user's name"), // <2>
fieldWithPath("contact.email").description("The user's email address")))) // <3>
.when().get("/user/5").then().assertThat().statusCode(is(200));
// end::response[]
}
public void subsection() throws Exception {
// tag::subsection[]
RestAssured.given(this.spec).accept("application/json")
.filter(document("user",
responseFields(subsectionWithPath("contact").description("The user's contact details")))) // <1>
.when().get("/user/5").then().assertThat().statusCode(is(200));
// end::subsection[]
}
public void explicitType() throws Exception {
RestAssured.given(this.spec).accept("application/json")
// tag::explicit-type[]
.filter(document("user", responseFields(fieldWithPath("contact.email").type(JsonFieldType.STRING) // <1>
.description("The user's email address"))))
// end::explicit-type[]
.when().get("/user/5").then().assertThat().statusCode(is(200));
}
public void constraints() throws Exception {
RestAssured.given(this.spec).accept("application/json")
// tag::constraints[]
.filter(document("create-user",
requestFields(attributes(key("title").value("Fields for user creation")), // <1>
fieldWithPath("name").description("The user's name")
.attributes(key("constraints").value("Must not be null. Must not be empty")), // <2>
fieldWithPath("email").description("The user's email address")
.attributes(key("constraints").value("Must be a valid email address"))))) // <3>
// end::constraints[]
.when().post("/users").then().assertThat().statusCode(is(200));
}
public void descriptorReuse() throws Exception {
FieldDescriptor[] book = new FieldDescriptor[] { fieldWithPath("title").description("Title of the book"),
fieldWithPath("author").description("Author of the book") };
// tag::single-book[]
RestAssured.given(this.spec).accept("application/json").filter(document("book", responseFields(book))) // <1>
.when().get("/books/1").then().assertThat().statusCode(is(200));
// end::single-book[]
// tag::book-array[]
RestAssured.given(this.spec).accept("application/json")
.filter(document("books", responseFields(fieldWithPath("[]").description("An array of books")) // <1>
.andWithPrefix("[].", book))) // <2>
.when().get("/books").then().assertThat().statusCode(is(200));
// end::book-array[]
}
public void fieldsSubsection() throws Exception {
// tag::fields-subsection[]
RestAssured.given(this.spec).accept("application/json")
.filter(document("location", responseFields(beneathPath("weather.temperature"), // <1>
fieldWithPath("high").description("The forecast high in degrees celcius"), // <2>
fieldWithPath("low").description("The forecast low in degrees celcius"))))
.when().get("/locations/1").then().assertThat().statusCode(is(200));
// end::fields-subsection[]
}
public void bodySubsection() throws Exception {
// tag::body-subsection[]
RestAssured.given(this.spec).accept("application/json")
.filter(document("location", responseBody(beneathPath("weather.temperature")))) // <1>
.when().get("/locations/1").then().assertThat().statusCode(is(200));
// end::body-subsection[]
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.RestAssured;
import io.restassured.specification.RequestSpecification;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.removeHeaders;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
public class PerTestPreprocessing {
private RequestSpecification spec;
public void general() throws Exception {
// tag::preprocessing[]
RestAssured.given(this.spec).filter(document("index", preprocessRequest(removeHeaders("Foo")), // <1>
preprocessResponse(prettyPrint()))) // <2>
.when().get("/").then().assertThat().statusCode(is(200));
// end::preprocessing[]
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.RestAssured;
import io.restassured.specification.RequestSpecification;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.requestParameters;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
public class RequestParameters {
private RequestSpecification spec;
public void getQueryStringSnippet() throws Exception {
// tag::request-parameters-query-string[]
RestAssured.given(this.spec).filter(document("users", requestParameters(// <1>
parameterWithName("page").description("The page to retrieve"), // <2>
parameterWithName("per_page").description("Entries per page")))) // <3>
.when().get("/users?page=2&per_page=100") // <4>
.then().assertThat().statusCode(is(200));
// end::request-parameters-query-string[]
}
public void postFormDataSnippet() throws Exception {
// tag::request-parameters-form-data[]
RestAssured.given(this.spec)
.filter(document("create-user",
requestParameters(parameterWithName("username").description("The user's username"))))
.formParam("username", "Tester") // <1>
.when().post("/users") // <2>
.then().assertThat().statusCode(is(200));
// end::request-parameters-form-data[]
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import io.restassured.RestAssured;
import io.restassured.specification.RequestSpecification;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestPartBody;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestPartFields;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
public class RequestPartPayload {
private RequestSpecification spec;
public void fields() throws Exception {
// tag::fields[]
Map<String, String> metadata = new HashMap<>();
metadata.put("version", "1.0");
RestAssured.given(this.spec).accept("application/json")
.filter(document("image-upload", requestPartFields("metadata", // <1>
fieldWithPath("version").description("The version of the image")))) // <2>
.when().multiPart("image", new File("image.png"), "image/png").multiPart("metadata", metadata)
.post("images").then().assertThat().statusCode(is(200));
// end::fields[]
}
public void body() throws Exception {
// tag::body[]
Map<String, String> metadata = new HashMap<>();
metadata.put("version", "1.0");
RestAssured.given(this.spec).accept("application/json")
.filter(document("image-upload", requestPartBody("metadata"))) // <1>
.when().multiPart("image", new File("image.png"), "image/png").multiPart("metadata", metadata)
.post("images").then().assertThat().statusCode(is(200));
// end::body[]
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import io.restassured.RestAssured;
import io.restassured.specification.RequestSpecification;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.request.RequestDocumentation.partWithName;
import static org.springframework.restdocs.request.RequestDocumentation.requestParts;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
public class RequestParts {
private RequestSpecification spec;
public void upload() throws Exception {
// tag::request-parts[]
RestAssured.given(this.spec).filter(document("users", requestParts(// <1>
partWithName("file").description("The file to upload")))) // <2>
.multiPart("file", "example") // <3>
.when().post("/upload") // <4>
.then().statusCode(is(200));
// end::request-parts[]
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2014-2021 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
*
* https://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 com.example.restassured;
import com.example.SnippetReuse;
import io.restassured.RestAssured;
import io.restassured.specification.RequestSpecification;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
public class RestAssuredSnippetReuse extends SnippetReuse {
private RequestSpecification spec;
public void documentation() throws Exception {
// tag::use[]
RestAssured.given(this.spec).accept("application/json").filter(document("example", this.pagingLinks.and(// <1>
linkWithRel("alpha").description("Link to the alpha resource"),
linkWithRel("bravo").description("Link to the bravo resource")))).get("/").then().assertThat()
.statusCode(is(200));
// end::use[]
}
}