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:
@@ -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:
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user