Add support for using REST Assured to generate documentation snippets

This commit adds a new module, spring-restdocs-restassured, that
can be used to generate documentation snippets when testing a service
with REST Assured.

Please refer to the updated reference documentation for details.

Thanks to Johan Haleby for making a change to REST Assured so that
path parameters could be documented.

Closes gh-102
This commit is contained in:
Andy Wilkinson
2015-09-07 14:36:42 +01:00
parent f73108ae36
commit 130b411e2a
66 changed files with 3361 additions and 433 deletions

View File

@@ -6,7 +6,12 @@
[[configuration-uris]]
=== Documented URIs
The default configuration for URIs documented by Spring REST Docs is:
NOTE: As REST Assured tests a service by making actual HTTP requests, the documented
URIs cannot be customized in this way. You should use the
<<customizing-requests-and-responses-preprocessors-modify-uris, REST-Assured specific
preprocessor>> instead.
When using MockMvc, the default configuration for URIs documented by Spring REST Docs is:
|===
|Setting |Default
@@ -21,12 +26,12 @@ The default configuration for URIs documented by Spring REST Docs is:
|`8080`
|===
This configuration is applied by `RestDocumentationMockMvcConfigurer`. You can use its API
This configuration is applied by `MockMvcRestDocumentationConfigurer`. You can use its API
to change one or more of the defaults to suit your needs:
[source,java,indent=0]
----
include::{examples-dir}/com/example/CustomUriConfiguration.java[tags=custom-uri-configuration]
include::{examples-dir}/com/example/mockmvc/CustomUriConfiguration.java[tags=custom-uri-configuration]
----
TIP: To configure a request's context path, use the `contextPath` method on
@@ -38,12 +43,19 @@ TIP: To configure a request's context path, use the `contextPath` method on
=== Snippet encoding
The default encoding used by Asciidoctor is `UTF-8`. Spring REST Docs adopts the same
default for the snippets that it generates. If you require an encoding other than `UTF-8`,
use `RestDocumentationMockMvcConfigurer` to configure it:
default for the snippets that it generates. You can change the default snippet encoding
using the `RestDocumentationConfigurer` API. For example, to use `ISO-8859-1`:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/CustomEncoding.java[tags=custom-encoding]
include::{examples-dir}/com/example/mockmvc/CustomEncoding.java[tags=custom-encoding]
----
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/CustomEncoding.java[tags=custom-encoding]
----
@@ -57,11 +69,18 @@ Three snippets are produced by default:
- `http-request`
- `http-response`
This default configuration is applied by `RestDocumentationMockMvcConfigurer`. You can use
its API to change the configuration. For example, to only produce the `curl-request`
You can change the default snippet configuration during setup using the
`RestDocumentationConfigurer` API. For example, to only produce the `curl-request`
snippet by default:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/CustomDefaultSnippetsConfiguration.java[tags=custom-default-snippets]
include::{examples-dir}/com/example/mockmvc/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]
----

View File

@@ -10,9 +10,18 @@ and/or an `OperationResponsePreprocessor`. Instances can be obtained using the
static `preprocessRequest` and `preprocessResponse` methods on `Preprocessors`. For
example:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/PerTestPreprocessing.java[tags=preprocessing]
include::{examples-dir}/com/example/mockmvc/PerTestPreprocessing.java[tags=preprocessing]
----
<1> Apply a request preprocessor that will remove the header named `Foo`.
<2> Apply a response preprocessor that will pretty print its content.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/PerTestPreprocessing.java[tags=preprocessing]
----
<1> Apply a request preprocessor that will remove the header named `Foo`.
<2> Apply a response preprocessor that will pretty print its content.
@@ -22,25 +31,44 @@ so by configuring the preprocessors in your `@Before` method and using the
<<documentating-your-api-parameterized-output-directories, support for parameterized
output directories>>:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/EveryTestPreprocessing.java[tags=setup]
include::{examples-dir}/com/example/mockmvc/EveryTestPreprocessing.java[tags=setup]
----
<1> Create the `RestDocumentationResultHandler`, configured to preprocess the request
<1> Create a `RestDocumentationResultHandler`, configured to preprocess the request
and response.
<2> Create the `MockMvc` instance, configured to always call the documentation result
<2> Create a `MockMvc` instance, configured to always call the documentation result
handler.
Then, in each test, the `RestDocumentationResultHandler` can be configured with anything
test-specific. For example:
[source,java,indent=0]
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/EveryTestPreprocessing.java[tags=use]
include::{examples-dir}/com/example/restassured/EveryTestPreprocessing.java[tags=setup]
----
<1> Create a `RestDocumentationFilter`, configured to preprocess the request
and response.
<2> Create a `RequestSpecification` instance, configured to always call the documentation
filter.
Then, in each test, any configuration specific to that test can be performed. For example:
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/mockmvc/EveryTestPreprocessing.java[tags=use]
----
<1> Document the links specific to the resource that is being tested
<2> The `perform` call will automatically produce the documentation snippets due to the
use of `alwaysDo` above.
<2> The request and response will be preprocessed due to the use of `alwaysDo` above.
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/EveryTestPreprocessing.java[tags=use]
----
<1> Document the links specific to the resource that is being tested
<2> The request and response will be preprocessed due to the configuration of the
`RequestSpecification` in the `setUp` method.
Various built in preprocessors, including those illustrated above, are available via the
static methods on `Preprocessors`. See <<Preprocessors, below>> for further details.
@@ -86,6 +114,20 @@ from the request or response.
replacing content in a request or response. Any occurrences of a regular expression are
replaced.
[[customizing-requests-and-responses-preprocessors-modify-uris]]
==== Modifying URIs
TIP: If you are using MockMvc, URIs should be customized by <<configuration-uris, changing
the configuration>>.
`modifyUris` on `RestAssuredPreprocessors` can be used to modify any URIs in a request
or a response. When using REST Assured, this allows you to customize the URIs that appear
in the documentation while testing a local instance of the service.
[[customizing-requests-and-responses-preprocessors-writing-your-own]]
==== Writing your own preprocessor

View File

@@ -11,9 +11,22 @@ This section provides more details about using Spring REST Docs to document your
Spring REST Docs provides support for documenting the links in a
https://en.wikipedia.org/wiki/HATEOAS[Hypermedia-based] API:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/Hypermedia.java[tag=links]
include::{examples-dir}/com/example/mockmvc/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`.
[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
@@ -47,14 +60,23 @@ Two link formats are understood by default:
If you are using Atom or HAL-format links but with a different content type you can
provide one of the built-in `LinkExtractor` implementations to `links`. For example:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/Hypermedia.java[tag=explicit-extractor]
include::{examples-dir}/com/example/mockmvc/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
[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.
@@ -65,9 +87,22 @@ In addition to the hypermedia-specific support <<documenting-your-api-hypermedia
above>>, support for general documentation of request and response payloads is also
provided. For example:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/Payload.java[tags=response]
include::{examples-dir}/com/example/mockmvc/Payload.java[tags=response]
----
<1> Configure Spring REST docs to produce a snippet describing the fields in the response
payload. To document a request `requestFields` can be used. Both are static methods on
`org.springframework.restdocs.payload.PayloadDocumentation`.
<2> Expect a field with the path `contact`. Uses the static `fieldWithPath` method on
`org.springframework.restdocs.payload.PayloadDocumentation`.
<3> Expect a field with the path `contact.email`.
[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 `requestFields` can be used. Both are static methods on
@@ -223,9 +258,17 @@ The type can also be set explicitly using the `type(Object)` method on
in the documentation. Typically, one of the values enumerated by `JsonFieldType` will be
used:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/Payload.java[tags=explicit-type]
include::{examples-dir}/com/example/mockmvc/Payload.java[tags=explicit-type]
----
<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`.
@@ -255,9 +298,10 @@ method will be used in the documentation.
A request's parameters can be documented using `requestParameters`. Request parameters
can be included in a `GET` request's query string. For example:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/RequestParameters.java[tags=request-parameters-query-string]
include::{examples-dir}/com/example/mockmvc/RequestParameters.java[tags=request-parameters-query-string]
----
<1> Perform a `GET` request with two parameters, `page` and `per_page` in the query
string.
@@ -268,14 +312,37 @@ include::{examples-dir}/com/example/RequestParameters.java[tags=request-paramete
`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.
Request parameters can also be included as form data in the body of a POST request:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/RequestParameters.java[tags=request-parameters-form-data]
include::{examples-dir}/com/example/mockmvc/RequestParameters.java[tags=request-parameters-form-data]
----
<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 both cases, the result is a snippet named `request-parameters.adoc` that contains a
table describing the parameters that are supported by the resource.
@@ -294,9 +361,10 @@ above.
A request's path parameters can be documented using `pathParameters`. For example:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/PathParameters.java[tags=path-parameters]
include::{examples-dir}/com/example/mockmvc/PathParameters.java[tags=path-parameters]
----
<1> Perform a `GET` request with two path parameters, `latitude` and `longitude`.
<2> Configure Spring REST Docs to produce a snippet describing the request's path
@@ -306,6 +374,19 @@ include::{examples-dir}/com/example/PathParameters.java[tags=path-parameters]
`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.
@@ -329,9 +410,10 @@ above.
The headers in a request or response can be documented using `requestHeaders` and
`responseHeaders` respectively. For example:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/HttpHeaders.java[tags=headers]
include::{examples-dir}/com/example/mockmvc/HttpHeaders.java[tags=headers]
----
<1> Perform a `GET` request with an `Authorization` header that uses basic authentication
<2> Configure Spring REST Docs to produce a snippet describing the request's headers.
@@ -342,6 +424,20 @@ include::{examples-dir}/com/example/HttpHeaders.java[tags=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.
@@ -436,8 +532,7 @@ class in the Spring HATEOAS-based sample illustrates the latter approach.
[[documenting-your-api-default-snippets]]
=== Default snippets
A number of snippets are produced automatically when you document a call to
`MockMvc.perform`:
A number of snippets are produced automatically when you document a request and response.
[cols="1,3"]
|===
@@ -489,23 +584,30 @@ are supported:
| The nome of the test class, formatted using snake_case
| {step}
| The count of calls to MockMvc.perform in the current test
| The count of calls made to the service in the current test
|===
For example, `document("{class-name}/{method-name}")` in a test method named
`creatingANote` on the test class `GettingStartedDocumentation`, will write
snippets into a directory named `getting-started-documentation/creating-a-note`.
A parameterized output directory is particularly useful in combination with Spring MVC
Test's `alwaysDo` functionality. It allows documentation to be configured once in a setup
method:
A parameterized output directory is particularly useful in combination with an `@Before`
method. It allows documentation to be configured once in a setup method and then reused
in every test in the class:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/AlwaysDo.java[tags=always-do]
include::{examples-dir}/com/example/mockmvc/ParameterizedOutput.java[tags=parameterized-output]
----
With this configuration in place, every call to `MockMvc.perform` will produce
[source,java,indent=0,role="secondary"]
.REST Assured
----
include::{examples-dir}/com/example/restassured/ParameterizedOutput.java[tags=parameterized-output]
----
With this configuration in place, every call to the service you are testing will produce
the <<documenting-your-api-default-snippets,default snippets>> without any further
configuration. Take a look at the `GettingStartedDocumentation` classes in each of the
sample applications to see this functionality in action.
@@ -549,9 +651,19 @@ A concrete example of the above is the addition of a constraints column and a ti
documenting request fields. The first step is to provide a `constraints` attribute for
each field that you are documenting and to provide a `title` attribute:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/Payload.java[tags=constraints]
include::{examples-dir}/com/example/mockmvc/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
[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

View File

@@ -83,7 +83,9 @@ the configuration are described below.
</plugins>
</build>
----
<1> Add a dependency on `spring-restdocs-mockmvc` in the `test` scope.
<1> Add a dependency on `spring-restdocs-mockmvc` in the `test` scope. If you want to use
REST Assured rather than MockMvc, add a dependency on `spring-restdocs-restassured`
instead.
<2> Configure a property to define the output location for generated snippets.
<3> Add the SureFire plugin and configure it to include files whose names end with
`Documentation.java`.
@@ -120,7 +122,9 @@ project's jar you should use the `prepare-package` phase.
}
----
<1> Apply the Asciidoctor plugin.
<2> Add a dependency on `spring-restdocs-mockmvc` in the `testCompile` configuration.
<2> Add a dependency on `spring-restdocs-mockmvc` in the `testCompile` configuration. If
you want to use REST Assured rather than MockMvc, add a dependency on
`spring-restdocs-restassured` instead.
<3> Configure a property to define the output location for generated snippets.
<4> Configure the `test` task to add the snippets directory as an output.
<5> Configure the `asciidoctor` task
@@ -199,14 +203,16 @@ from where it will be included in the jar file.
[[getting-started-documentation-snippets]]
=== Generating documentation snippets
Spring REST Docs uses {spring-framework-docs}/#spring-mvc-test-framework[Spring's MVC Test
framework] to make requests to the service that you are documenting. It then produces
documentation snippets for request and resulting response.
Spring REST Docs uses JUnit and
{spring-framework-docs}/#spring-mvc-test-framework[Spring's MVC Test framework] or
http://www.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.
[[getting-started-documentation-snippets-setup]]
==== Setting up Spring MVC test
==== Setting up your tests
The first step in generating documentation snippets is to declare a `public`
`RestDocumentation` field that's annotated as a JUnit `@Rule`. The `RestDocumentation`
@@ -214,47 +220,59 @@ rule is configured with the output directory into which generated snippets shoul
written. This output directory should match the snippets directory that you have
configured in your `build.gradle` or `pom.xml` file.
For Maven (`pom.xml` that will typically be `target/generated-snippets`:
For Maven (`pom.xml` that will typically be `target/generated-snippets` and for
Gradle (`build.gradle`) it will typically be `build/generated-snippets`:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.Maven
----
@Rule
public RestDocumentation restDocumentation = new RestDocumentation("target/generated-snippets");
----
And for Gradle (`build.gradle`) it will typically be `build/generated-snippets`:
[source,java,indent=0]
[source,java,indent=0,role="secondary"]
.Gradle
----
@Rule
public RestDocumentation restDocumentation = new RestDocumentation("build/generated-snippets");
----
Next, provide an `@Before` method that creates a `MockMvc` instance:
Next, provide an `@Before` method to configure MockMvc or REST Assured:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/ExampleApplicationTests.java[tags=mock-mvc-setup]
include::{examples-dir}/com/example/mockmvc/ExampleApplicationTests.java[tags=setup]
----
The `MockMvc` instance is configured using a `RestDocumentationMockMvcConfigurer`. An
<1> The `MockMvc` instance is configured using a `MockMvcRestDocumentationConfigurer`. An
instance of this class can be obtained from the static `documentationConfiguration()`
method on `org.springframework.restdocs.mockmvc.MockMvcRestDocumentation`.
`RestDocumentationMockMvcConfigurer` applies sensible defaults and also provides an API
for customizing the configuration. Refer to the
<<configuration, configuration section>> for more information.
[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`. An instance of this class can be obtained from the static
`documentationConfiguration()` method on
`org.springframework.restdocs.restassured.RestAssuredRestDocumentation`.
The configurer applies sensible defaults and also provides an API for customizing the
configuration. Refer to the <<configuration, configuration section>> for more information.
[[getting-started-documentation-snippets-invoking-the-service]]
==== Invoking the RESTful service
Now that a `MockMvc` instance has been created, it can be used to invoke the RESTful
Now that the testing framework has been configured, it can be used to invoke the RESTful
service and document the request and response. For example:
[source,java,indent=0]
[source,java,indent=0,role="primary"]
.MockMvc
----
include::{examples-dir}/com/example/InvokeService.java[tags=invoke-service]
include::{examples-dir}/com/example/mockmvc/InvokeService.java[tags=invoke-service]
----
<1> Invoke the root (`/`) of the service and indicate that an `application/json` response
is required.
@@ -265,6 +283,21 @@ a `RestDocumentationResultHandler`. An instance of this class can be obtained fr
static `document` method on
`org.springframework.restdocs.mockmvc.MockMvcRestDocumentation`.
[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 initialised 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`
that will be located beneath the configured output directory. The snippets are written by
a `RestDocumentationFilter`. An instance of this class can be obtained from the
static `document` method on
`org.springframework.restdocs.restassured.RestAssuredRestDocumentation`.
<4> Invoke the root (`/`) of the service.
<5> Assert that the service produce the expected response.
By default, three snippets are written:
* `<output-directory>/index/curl-request.adoc`

View File

@@ -10,9 +10,10 @@ http://asciidoctor.org[Asciidoctor]. Asciidoctor processes plain text and produc
HTML, styled and layed out to suit your needs.
Spring REST Docs makes use of snippets produced by tests written with
{spring-framework-docs}/#spring-mvc-test-framework[Spring MVC Test]. This test-driven
approach helps to guarantee the accuracy of your service's documentation. If a snippet is
incorrect the test that produces it will fail.
{spring-framework-docs}/#spring-mvc-test-framework[Spring MVC Test] or
http://www.rest-assured.io[REST Assured]. This test-driven approach helps to guarantee the
accuracy of your service's documentation. If a snippet is incorrect the test that produces
it will fail.
Documenting a RESTful service is largely about describing its resources. Two key parts
of each resource's description are the details of the HTTP requests that it consumes

View File

@@ -41,6 +41,7 @@ public class Constraints {
@NotNull
@Size(min = 8)
String password;
}
// end::constraints[]

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.example;
package com.example.mockmvc;
import static org.springframework.restdocs.curl.CurlDocumentation.curlRequest;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
@@ -27,7 +27,7 @@ import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
public class CustomDefaultSnippetsConfiguration {
public class CustomDefaultSnippets {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation("build");
@@ -41,8 +41,8 @@ public class CustomDefaultSnippetsConfiguration {
public void setUp() {
// tag::custom-default-snippets[]
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation).snippets()
.withDefaults(curlRequest()))
.apply(documentationConfiguration(this.restDocumentation)
.snippets().withDefaults(curlRequest()))
.build();
// end::custom-default-snippets[]
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.example;
package com.example.mockmvc;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
@@ -27,7 +27,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
public class CustomEncoding {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation("build");
@@ -40,8 +40,8 @@ public class CustomEncoding {
public void setUp() {
// tag::custom-encoding[]
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation).snippets()
.withEncoding("ISO-8859-1"))
.apply(documentationConfiguration(this.restDocumentation)
.snippets().withEncoding("ISO-8859-1"))
.build();
// end::custom-encoding[]
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.example;
package com.example.mockmvc;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
@@ -27,7 +27,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
public class CustomUriConfiguration {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation("build");

View File

@@ -14,9 +14,11 @@
* limitations under the License.
*/
package com.example;
package com.example.mockmvc;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.RestDocumentation;
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
@@ -25,6 +27,7 @@ import org.springframework.web.context.WebApplicationContext;
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel;
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
@@ -34,20 +37,24 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
public class EveryTestPreprocessing {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation(
"target/generated-snippets");
private WebApplicationContext context;
// tag::setup[]
private MockMvc mockMvc;
private RestDocumentationResultHandler document;
// tag::setup[]
@Before
public void setup() {
this.document = document(
"{method-name}", // <1>
this.document = document("{method-name}", // <1>
preprocessRequest(removeHeaders("Foo")),
preprocessResponse(prettyPrint()));
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation))
.alwaysDo(this.document) // <2>
.build();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.example;
package com.example.mockmvc;
import org.junit.Before;
import org.junit.Rule;
@@ -29,8 +29,9 @@ import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.docu
public class ExampleApplicationTests {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation("target/generated-snippets");
// tag::mock-mvc-setup[]
public final RestDocumentation restDocumentation = new RestDocumentation(
"target/generated-snippets");
// tag::setup[]
@Autowired
private WebApplicationContext context;
@@ -39,8 +40,8 @@ public class ExampleApplicationTests {
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation))
.apply(documentationConfiguration(this.restDocumentation)) // <1>
.build();
}
// end::mock-mvc-setup[]
// end::setup[]
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.example;
package com.example.mockmvc;
import org.springframework.test.web.servlet.MockMvc;
@@ -32,19 +32,19 @@ public class HttpHeaders {
public void headers() throws Exception {
// tag::headers[]
this.mockMvc
.perform(get("/people").header("Authorization", "Basic dXNlcjpzZWNyZXQ=")) // <1>
.andExpect(status().isOk())
.andDo(document("headers",
requestHeaders( // <2>
headerWithName("Authorization").description(
"Basic auth credentials")), // <3>
responseHeaders( // <4>
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"))));
.perform(get("/people").header("Authorization", "Basic dXNlcjpzZWNyZXQ=")) // <1>
.andExpect(status().isOk())
.andDo(document("headers",
requestHeaders( // <2>
headerWithName("Authorization").description(
"Basic auth credentials")), // <3>
responseHeaders( // <4>
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"))));
// end::headers[]
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.example;
package com.example.mockmvc;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.example;
package com.example.mockmvc;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 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.
@@ -14,10 +14,7 @@
* limitations under the License.
*/
package com.example;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
package com.example.mockmvc;
import org.junit.Before;
import org.junit.Rule;
@@ -26,24 +23,25 @@ import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
public class AlwaysDo {
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
public class ParameterizedOutput {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation("build");
private MockMvc mockMvc;
private WebApplicationContext context;
// tag::always-do[]
// tag::parameterized-output[]
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation))
.alwaysDo(document("{method-name}/{step}/"))
.build();
.alwaysDo(document("{method-name}/{step}/")).build();
}
// end::always-do[]
// end::parameterized-output[]
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.example;
package com.example.mockmvc;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.example;
package com.example.mockmvc;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
@@ -51,7 +51,6 @@ private MockMvc mockMvc;
.andDo(document("index", responseFields(
fieldWithPath("contact.email")
.type(JsonFieldType.STRING) // <1>
.optional()
.description("The user's email address"))));
// end::explicit-type[]
}
@@ -61,16 +60,13 @@ private MockMvc mockMvc;
.andExpect(status().isOk())
// tag::constraints[]
.andDo(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>
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[]
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.example;
package com.example.mockmvc;
import org.springframework.test.web.servlet.MockMvc;
@@ -33,8 +33,8 @@ public class PerTestPreprocessing {
public void general() throws Exception {
// tag::preprocessing[]
this.mockMvc.perform(get("/")).andExpect(status().isOk())
.andDo(document("index", preprocessRequest(removeHeaders("Foo")), // <1>
preprocessResponse(prettyPrint()))); // <2>
.andDo(document("index", preprocessRequest(removeHeaders("Foo")), // <1>
preprocessResponse(prettyPrint()))); // <2>
// end::preprocessing[]
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2016 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.example;
package com.example.mockmvc;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
@@ -39,7 +39,7 @@ public class RequestParameters {
)));
// end::request-parameters-query-string[]
}
public void postFormDataSnippet() throws Exception {
// tag::request-parameters-form-data[]
this.mockMvc.perform(post("/users").param("username", "Tester")) // <1>

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.restassured;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.RestDocumentation;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.specification.RequestSpecification;
import static org.springframework.restdocs.curl.CurlDocumentation.curlRequest;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
public class CustomDefaultSnippets {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation("build");
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-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.restassured;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.RestDocumentation;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.specification.RequestSpecification;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
public class CustomEncoding {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation("build");
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,72 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.restassured;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.RestDocumentation;
import org.springframework.restdocs.restassured.RestDocumentationFilter;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.specification.RequestSpecification;
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.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;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
public class EveryTestPreprocessing {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation(
"target/generated-snippets");
// tag::setup[]
private RequestSpecification spec;
private RestDocumentationFilter document;
@Before
public void setup() {
this.document = document("{method-name}",
preprocessRequest(removeHeaders("Foo")),
preprocessResponse(prettyPrint())); // <1>
this.spec = new RequestSpecBuilder()
.addFilter(documentationConfiguration(this.restDocumentation))
.addFilter(this.document)// <2>
.build();
}
// end::setup[]
public void use() throws Exception {
// tag::use[]
this.document.snippets( // <1>
links(linkWithRel("self").description("Canonical self link")));
RestAssured.given(this.spec) // <2>
.when().get("/")
.then().assertThat().statusCode(is(200));
// end::use[]
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.restassured;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.RestDocumentation;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.specification.RequestSpecification;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
public class ExampleApplicationTests {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation(
"build/generated-snippets");
// 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,51 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.restassured;
import com.jayway.restassured.RestAssured;
import com.jayway.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("Authroization", "Basic dXNlcjpzZWNyZXQ=") // <4>
.when().get("/people")
.then().assertThat().statusCode(is(200));
// end::headers[]
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.restassured;
import com.jayway.restassured.RestAssured;
import com.jayway.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,38 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.restassured;
import com.jayway.restassured.RestAssured;
import com.jayway.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,46 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.restassured;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.restdocs.RestDocumentation;
import com.jayway.restassured.builder.RequestSpecBuilder;
import com.jayway.restassured.specification.RequestSpecification;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.document;
import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration;
public class ParameterizedOutput {
@Rule
public final RestDocumentation restDocumentation = new RestDocumentation(
"build/generated-snippets");
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-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.restassured;
import com.jayway.restassured.RestAssured;
import com.jayway.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,75 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.restassured;
import org.springframework.restdocs.payload.JsonFieldType;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.specification.RequestSpecification;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
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").description("The user's contact details"), // <2>
fieldWithPath("contact.email").description("The user's email address")))) // <3>
.when().get("/user/5")
.then().assertThat().statusCode(is(200));
// end::response[]
}
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));
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.restassured;
import com.jayway.restassured.RestAssured;
import com.jayway.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,53 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.restassured;
import com.jayway.restassured.RestAssured;
import com.jayway.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[]
}
}