Edit the testing part of the reference documentation

I edited for spelling, punctuation, grammar, usage,
and corporate voice.

I also added cross-references and links to the Javadoc.
This commit is contained in:
Jay Bryant
2018-08-30 10:29:17 -05:00
committed by Brian Clozel
parent 395e3d008c
commit 95ff22cb7e
3 changed files with 2278 additions and 1607 deletions

View File

@@ -8420,7 +8420,7 @@ the `Environment` or ,declaratively, by using the `spring.profiles.default` prop
[[beans-property-source-abstraction]]
=== `PropertySource` abstraction
=== `PropertySource` Abstraction
Spring's `Environment` abstraction provides search operations over a configurable
hierarchy of property sources. Consider the following listing:

View File

@@ -3,16 +3,12 @@
`WebTestClient` is a thin shell around <<web-reactive.adoc#webflux-webclient, WebClient>>,
using it to perform requests and exposing a dedicated, fluent API for verifying responses.
`WebTestClient` bind to a WebFlux application using a
`WebTestClient` binds to a WebFlux application by using a
<<testing.adoc#mock-objects-web-reactive,mock request and response>>, or it can test any
web server over an HTTP connection.
[TIP]
====
Kotlin users, please see <<languages.adoc#kotlin-webtestclient-issue,this section>>
TIP: Kotlin users: See <<languages.adoc#kotlin-webtestclient-issue,this section>>
related to use of the `WebTestClient`.
====
@@ -26,48 +22,53 @@ a URL to connect to a running server.
[[webtestclient-controller-config]]
=== Bind to controller
=== Bind to Controller
Use this server setup to test one `@Controller` at a time:
The following example shows how to create a server setup to test one `@Controller` at a time:
====
[source,java,intent=0]
[subs="verbatim,quotes"]
----
client = WebTestClient.bindToController(new TestController()).build();
----
====
The above loads the <<web-reactive.adoc#webflux-config,WebFlux Java config>> and
registers the given controller. The resulting WebFlux application will be tested
without an HTTP server using mock request and response objects. There are more methods
on the builder to customize the default WebFlux Java config.
The preceding example loads the <<web-reactive.adoc#webflux-config,WebFlux Java configuration>> and
registers the given controller. The resulting WebFlux application is tested
without an HTTP server by using mock request and response objects. There are more methods
on the builder to customize the default WebFlux Java configuration.
[[webtestclient-fn-config]]
=== Bind to RouterFunction
=== Bind to Router Function
Use this option to set up a server from a
The folloiwng example shows how to set up a server from a
<<web-reactive.adoc#webflux-fn,RouterFunction>>:
====
[source,java,intent=0]
[subs="verbatim,quotes"]
----
RouterFunction<?> route = ...
client = WebTestClient.bindToRouterFunction(route).build();
----
====
Internally the provided configuration is passed to `RouterFunctions.toWebHandler`.
The resulting WebFlux application will be tested without an HTTP server using mock
Internally, the configuration is passed to `RouterFunctions.toWebHandler`.
The resulting WebFlux application is tested without an HTTP server by using mock
request and response objects.
[[webtestclient-context-config]]
=== Bind to ApplicationContext
=== Bind to `ApplicationContext`
Use this option to setup a server from the Spring configuration of your application, or
The following example shows how to setup a server from the Spring configuration of your application or
some subset of it:
====
[source,java,intent=0]
[subs="verbatim,quotes"]
----
@@ -90,35 +91,40 @@ some subset of it:
<1> Specify the configuration to load
<2> Inject the configuration
<3> Create the `WebTestClient`
====
Internally the provided configuration is passed to `WebHttpHandlerBuilder` to set up
the request processing chain, see
Internally, the configuration is passed to `WebHttpHandlerBuilder` to set up
the request processing chain. See
<<web-reactive.adoc#webflux-web-handler-api,WebHandler API>> for more details. The
resulting WebFlux application will be tested without an HTTP server using mock request
resulting WebFlux application is tested without an HTTP server by using mock request
and response objects.
[[webtestclient-server-config]]
=== Bind to server
=== Bind to Server
This server setup option allows you to connect to a running server:
The following server setup option lets you connect to a running server:
====
[source,java,intent=0]
[subs="verbatim,quotes"]
----
client = WebTestClient.bindToServer().baseUrl("http://localhost:8080").build();
----
====
[[webtestclient-client-config]]
=== Client builder
=== Client Builder
In addition to the server setup options above, you can also configure client
options including base URL, default headers, client filters, and others. These options
In addition to the server setup options described earlier, you can also configure client
options, including base URL, default headers, client filters, and others. These options
are readily available following `bindToServer`. For all others, you need to use
`configureClient()` to transition from server to client configuration as shown below:
`configureClient()` to transition from server to client configuration, as follows:
====
[source,java,intent=0]
[subs="verbatim,quotes"]
----
@@ -127,19 +133,20 @@ are readily available following `bindToServer`. For all others, you need to use
.baseUrl("/test")
.build();
----
====
[[webtestclient-tests]]
== Writing tests
== Writing Tests
`WebTestClient` is a thin shell around <<web-reactive.adoc#webflux-webclient,WebClient>>.
It provides an identical API up to the point of performing a request via `exchange()`.
It provides an identical API up to the point of performing a request by using `exchange()`.
What follows after `exchange()` is a chained API workflow to verify responses.
Typically you start by asserting the response status and headers:
Typically, you start by asserting the response status and headers, as follows:
====
[source,java,intent=0]
[subs="verbatim,quotes"]
----
@@ -150,15 +157,17 @@ Typically you start by asserting the response status and headers:
.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
// ...
----
====
Then you specify how to decode and consume the response body:
* `expectBody(Class<T>)` -- decode to single object.
* `expectBodyList(Class<T>)` -- decode and collect objects to `List<T>`.
* `expectBody()` -- decode to `byte[]` for <<webtestclient-json>> or empty body.
* `expectBody(Class<T>)`: Decode to single object.
* `expectBodyList(Class<T>)`: Decode and collect objects to `List<T>`.
* `expectBody()`: Decode to `byte[]` for <<webtestclient-json>> or an empty body.
Then you can use built-in assertions for the body. Here is one example:
Then you can use built-in assertions for the body. The following example shows one way to do so:
====
[source,java,intent=0]
[subs="verbatim,quotes"]
----
@@ -167,9 +176,11 @@ Then you can use built-in assertions for the body. Here is one example:
.expectStatus().isOk()
.expectBodyList(Person.class).hasSize(3).contains(person);
----
====
You can go beyond the built-in assertions and create your own:
You can also go beyond the built-in assertions and create your own, as the following example shows:
====
----
client.get().uri("/persons/1")
.exchange()
@@ -179,9 +190,11 @@ You can go beyond the built-in assertions and create your own:
// custom assertions (e.g. AssertJ)...
});
----
====
You can also exit the workflow and get a result:
You can also exit the workflow and get a result, as follows:
====
----
EntityExchangeResult<Person> result = client.get().uri("/persons/1")
.exchange()
@@ -189,22 +202,22 @@ You can also exit the workflow and get a result:
.expectBody(Person.class)
.returnResult();
----
====
[TIP]
====
When you need to decode to a target type with generics, look for the overloaded methods
TIP: When you need to decode to a target type with generics, look for the overloaded methods
that accept
{api-spring-framework}/core/ParameterizedTypeReference.html[ParameterizedTypeReference]
{api-spring-framework}/core/ParameterizedTypeReference.html[`ParameterizedTypeReference`]
instead of `Class<T>`.
====
[[webtestclient-no-content]]
=== No content
=== No Content
If the response has no content, or you don't care if it does, use `Void.class` which ensures
that resources are released:
If the response has no content (or you do not care if it does) use `Void.class`, which ensures
that resources are released. The following example shows how to do so:
====
[source,java,intent=0]
[subs="verbatim,quotes"]
----
@@ -213,9 +226,11 @@ that resources are released:
.expectStatus().isNotFound()
.expectBody(Void.class);
----
====
Or if you want to assert there is no response content, use this:
Alternatively, if you want to assert there is no response content, you can use code similar to the following:
====
[source,java,intent=0]
[subs="verbatim,quotes"]
----
@@ -225,16 +240,18 @@ Or if you want to assert there is no response content, use this:
.expectStatus().isCreated()
.expectBody().isEmpty();
----
====
[[webtestclient-json]]
=== JSON content
=== JSON Content
When you use `expectBody()` the response is consumed as a `byte[]`. This is useful for
raw content assertions. For example you can use
http://jsonassert.skyscreamer.org[JSONAssert] to verify JSON content:
When you use `expectBody()`, the response is consumed as a `byte[]`. This is useful for
raw content assertions. For example, you can use
http://jsonassert.skyscreamer.org[JSONAssert] to verify JSON content, as follows:
====
[source,java,intent=0]
[subs="verbatim,quotes"]
----
@@ -244,9 +261,11 @@ http://jsonassert.skyscreamer.org[JSONAssert] to verify JSON content:
.expectBody()
.json("{\"name\":\"Jane\"}")
----
====
You can also use https://github.com/jayway/JsonPath[JSONPath] expressions:
You can also use https://github.com/jayway/JsonPath[JSONPath] expressions, as follows:
====
[source,java,intent=0]
[subs="verbatim,quotes"]
----
@@ -257,15 +276,18 @@ You can also use https://github.com/jayway/JsonPath[JSONPath] expressions:
.jsonPath("$[0].name").isEqualTo("Jane")
.jsonPath("$[1].name").isEqualTo("Jason");
----
====
[[webtestclient-stream]]
=== Streaming responses
=== Streaming Responses
To test infinite streams (e.g. `"text/event-stream"`, `"application/stream+json"`),
you'll need to exit the chained API, via `returnResult`, immediately after response status
and header assertions, as shown below:
To test infinite streams (for example, `"text/event-stream"` or `"application/stream+json"`),
you need to exit the chained API (by using `returnResult`), immediately after the response status
and header assertions, as the following example shows:
====
[source,java,intent=0]
[subs="verbatim,quotes"]
----
@@ -276,11 +298,13 @@ and header assertions, as shown below:
.returnResult(MyEvent.class);
----
====
Now you can consume the `Flux<T>`, assert decoded objects as they come, and then
cancel at some point when test objects are met. We recommend using the `StepVerifier`
from the `reactor-test` module to do that, for example:
cancel at some point when test objectives are met. We recommend using the `StepVerifier`
from the `reactor-test` module to do that, as the following example shows:
====
[source,java,intent=0]
[subs="verbatim,quotes"]
----
@@ -293,13 +317,15 @@ from the `reactor-test` module to do that, for example:
.thenCancel()
.verify();
----
====
[[webtestclient-request-body]]
=== Request body
=== Request Body
When it comes to building requests, the `WebTestClient` offers an identical API as the
`WebClient` and the implementation is mostly a simple pass-through. Please refer
to the <<web-reactive.adoc#webflux-client-body,WebClient documentation>> for examples on
how to prepare a request with a body including submitting form data, multipart requests,
When it comes to building requests, the `WebTestClient` offers an API identical to the
`WebClient`, and the implementation is mostly a simple pass-through. See
the <<web-reactive.adoc#webflux-client-body,WebClient documentation>> for examples on
how to prepare a request with a body, including submitting form data, multipart requests,
and more.

File diff suppressed because it is too large Load Diff