Clearly separate how the result of an exchange is represented before
the response body has been read (e.g. assertions on status and headers
only) vs later after the body is extracted to a representation
(assertions on the extracted body) or is decoded to Flux<T> (e.g. for
use with a StepVerifier).
WebTestClient now defines all the steps from setup to performing
an exchange and applying expectations.
The order of expectations now ensures the response status and headers
are verified first since that's available before the body is consumed
and also because it determines how the body is to be decoded, i.e.
error vs success scenarios.
There is now a built-in option for verifying the response as a Map
along with Map-specific assertions.
There are similar options for verifying the response as a List as well
as whether to "collect" the list or "take" the first N elements from
the response stream.
Rather than returning ExchangeActions that contains ExchangeInfo and
applies a chain of assertions, the exchange operation in WebTestClient
now has an extra step to decode the response.
The outcome of that is ExchangeResult<T>, parameterized with the
decoded body type, and containing the request and response details,
also providing access to built-inassertions via an assertThat()
instance method.
This approach lends itself better to decoding and asserting response
body types with generecis. It is also more friendly to using any
assertion library such as AssertJ since you get the result first
and then deal with assertions.
This commit changes the `assertXmlEqual` implementation to compare
expected and actual XML documents without considering the order of XML
nodes.
Issue: SPR-15156
Put assertBodyXyz options behind a common assertBody() entry point
currently including "isEmpty" and "asMap" but in the future others
related to JSON content or XPath for example.
Now that ExchangeActions provides method to access the ExchangeInfo
it has been removed from constructors of assertion classes that
already have ExchangeActions.
This commit removes the parameterisation from ClientRequest, similarly
to ServerResponse. Dropping the parameterisation facilitates a
ClientRequest.from method that also copies the body of the target
request.
SPR-15234 Work in Progress
Before this change the write Publisher was saved and Mono.empty()
returned from the write metohd which did not properly implement
the write contract since no writing ("consuming") was done.
This can be a problem in some cases. For example the request may appear
to succeed even if the publisher produces an error later when
subscribed to later after request handling completes.
This commit introduces a writeHandler function in the mock request and
response. By default it "writes" by consuming the content immediately,
which allows it to return a Mono<Void> that properly reflects when
writing is done, and it also caches the data so it may be replayed
later for test assertions.
For streaming scenario a custom writeHandler may be registered which
allows the custom handling to determine how long to stream before
cancelling so request handling may complete.
Issue: SPR-14590
Prior to this commit, SpringJUnit4ConcurrencyTests was broken due to
recent additions of test methods in SampleTests.
This commit fixes the broken test by removing hard coded constants and
replacing them with dynamic lookups for JUnit 4 @Test methods.
This commit ensures that verifying a request, which includes finding
and updating expectations, is done synchronously to avoid concurrent
modification exceptions.
Technically SimpleRequestExpectationManager is not even expected to see
concurrent requests by definition but with
UnorderedRequestExpectationManager it can happen.
Issue: SPR-15029
MockServerHttpRequest and MockServerHttpResponse now extend the same
abstract base classes that server-specific implementations do and
therefore approximate their behavior more closely.
As an immediate consequence MockServerHttpRequest is read-only after
it is created. Instead it now exposes static builder methods similar
to those found in RequestEntity. This enforces more strictness as well
as recycling of requests in tests and provides nicer builder methods.
To simplify tests DefaultServerWebExchange now offers a constructor
with just a request and response, and automatically creating a
DefaultWebSessionManager.
The spring-test module now also contains client-side reactive mock
request and response implementations. The mock client request extends
the same AbstractClientHttpRequest as client-specific implementations
do. There is no abstract base class for client responses.
Issue: SPR-14590
After the upgrade to JUnit Jupiter 5.0 M3, JUnit Jupiter tests in the
Spring build were no longer executed due to the introduction of a
default test class name pattern.
This commit addresses this issue by making use of the
@IncludeClassNamePatterns to specify that *TestCase test classes should
be executed within the org.springframework.test.context.junit.jupiter
package.