Reorganize imports to ensure consistent ordering. This commit also
expands any `.*` static imports in favor of using fully-qualified
method references.
Issue: SPR-16968
Update all classes so that inner classes are always last. Also
ensure that utility classes are always final and have a private
constructor and make exceptions final whenever possible.
Issue: SPR-16968
Prior to this commit, the generated POMs for Spring Framework modules
would contain unneeded/harmful information from the Spring Framework
build:
1. The BOM imports applied to each module by the dependency
management plugin, for example for Netty or Reactor Netty.
Spring should not export that opinion to its POMs.
2. The exclusion of "org.slf4:jcl-over-slf4j" from *all* dependencies,
which made the POMs much larger than necessary and suggested to
developers that they should exclude it as well when using all those
listed dependencies. In fact, only Apache Tiles currently brings that
transitively.
This commit removes that information from the POMs.
The dependencyManagement Gradle plugin is disabled for POM generation
and we manually resolve the dependency versions during the generation
phase.
The Gradle build is streamlined to exclude "org.slf4:jcl-over-slf4j"
only when necessary.
Issue: SPR-16893
This commit adds FormContentFilter, which is the same as the
HttpPutFormContentFilter but also supports DELETE.
The HttpPutFormContentFilter is now deprecated.
Issue: SPR-16874
This commit removes all places where forwarded headers are checked
implicitly, on an ad-hoc basis.
ForwardedHeaderFilter is expected to be used instead providing
centralized control over using or discarding such headers.
Issue: SPR-16668
This commit introduces support for creating a new `ServerRequest` from
an existing instance. This is especially useful when filtering requests
in a HandlerFilterFunction.
Issue: SPR-16707
Prior to this commit, due to KT-5464 type inference issue there was not
proper way to provide body expectations with WebTestClient. This commit
provides a workaround by updating the existing Kotlin extension to
return a Kotlin compatible API.
Issue: SPR-15692
Gradle 4.6 provides built-in support for the JUnit Platform within the
standard `test` task.
This commit configures a custom `testJUnitJupiter` test task for
executing JUnit Jupiter tests directly on the JUnit Platform instead of
indirectly on JUnit 4 via @RunWith(JUnitPlatform.class).
This switch provides for better integration with Gradle's test reporting
and paves the way for a possible transition to the JUnit Platform in the
future.
Issue: SPR-16672
Prior to this commit it was impossible to have an individual
constructor argument in a @Nested (i.e., inner) test class injected via
@Autowired, @Qualifier, or @Value.
This is due to a bug in javac on JDK versions prior to 9, whereby
annotation lookups performed directly via the
java.lang.reflect.Parameter API fail for inner class constructors.
Specifically, the parameter annotations array in the compiled byte code
for the user's test class excludes an entry for the implicit enclosing
instance parameter for an inner class constructor.
This commit introduces a workaround in ParameterAutowireUtils for this
off-by-one error by transparently looking up annotations on the
preceding Parameter object (i.e., index - 1). In addition, this commit
relies on the change recently introduced in MethodParameter in order to
compensate for the same JDK bug (see SPR-16652).
Issue: SPR-16653
This commit introduces @Nested tests to verify support for constructor
injection when using the SpringExtension.
One of the tests is disabled on Java 8 due to a bug in javac that was
first fixed in JDK 9.
See https://github.com/junit-team/junit5/issues/1345 for details.
This commit picks up where SPR-14498 left off by adding support for an
explicit target type when using JsonPath to perform an assertion against
the response content using a Hamcrest Matcher.
Specifically, there is a new overloaded value(Matcher<T>, Class<T>)
method in JsonPathResultMatchers for use with Hamcrest matchers where
the target type (i.e., Class<T>) can be specified.
Issue: SPR-16587
After this commit the use of interval in tests is combined with
take(n).onBackpressureBuffer(n) to ensure emissions don't fail if the
fixed rate is exceeded (e.g. on slow CI server).
Tests that verify N number of items followed by verifyOnComplete()
should set the number of emissions to N.
Tests that verify N number of items followed by thenCancel() should
set the number of buffered to an arbitrary number greater than N.
Previously MockHttpServletRequestBuilder calculated the pathInfo from the
provided URL without decoding the value. This meant that the pathInfo
incorrectly included URL encoded values.
Now MockHttpServletRequestBuilder properly decodes the pathInfo.
Fixes: SPR-16453
MockHttpServletResponse no longer calls flushBuffer on calls to
getContentAsByteArray and getContentAsString. The flushing doesn't
actually do anything useful but does commit the response leading to
unexpected side effects.
Issue: SPR-16430
This commit separates the creation of a response so that it is executed
after the synchronized block inside which requests need to be matched
and validated (for order and count).
This allows a ResponseCreator to be slow or block if it has to.
Issue: SPR-16319
This commit adds new header assertions for `WebTestClient`.
`doesNotExist` tests that a given header is not present:
.expectHeader().doesNotExist("Cache-Control");
`contentTypeCompatibleWith` tests for MediaType compatibility:
.expectHeader().contentTypeCompatibleWith("text/*");
Issue: SPR-16285
This avoids "IllegalStateException: Expectations already declared" when
a MockRestServiceServer is used after one request throws an exception.
Issues: SPR-16132
This commit decouples ExchangeResult from knowledge about
WiretapClientHttpRequest/Response both of which are now private to
WiretapConnector.
ExchangeResult takes ClientHttpRequest/Response instead along with
promises for the serialized request and response content in the form
of MonoProcessor<byte[]>.
This sets up the possibility for an ExchangeResult to be created
outside and independent of WebTestClient, should we decide to make its
constructor public.
Issue: SPR-16101
MockMvc now properly detects the presence of an AsyncContext and
re-uses the response instance used to start it.
This commit also includes a minor fix in
ResponseBodyEmitterReturnValueHandler to ensure it does not disable
ETag related content buffering for reactive return values that do not
result in streaming (e.g. single value or collections).
Issue: SPR-16067
The WebTestClient now takes advantage of the support for decoding
response to Void.class in WebClient so that applications can use
expectBody(Void.class) to the same effect as using
response.bodyToMono(Void.class) as documneted on WebClient#exchange.
The top-level, no-arg returnResult method (added very recently) has been
retracted, since the use of returnResult at that level, i.e. without
consuming the response content, should be used mainly for streaming.
It shouldn't be used for "no content" scenarios.
Documentation and Javadoc have been udpated accordingly.
Use the ClientResponse methods bodyToMono and bodyToFlux rather than
passing in a BodyExtractor so that WebTestclient now also benefits from
the recently improved handling of Void.class.
Concrete server and client, reactive request and response
implementations should not have to be accessed outside their package.
They could be seen as private to their HttpHandler adapters and
ClientHttpConnector's respectively.
The one exception, WebSocket upgrades in spring-webflux, is an internal
framework use case, accommodated via downcast + accessors in the
abstract base classes.
Prior to this commit, asking for a `Void` type using any of the
`ClientResponse#bodyTo*` methods would immediately return an empty
`Publisher` without consuming the response body.
Not doing so can lead to HTTP connection pool inconsistencies and/or
memory leaks, since:
* a connection that still has a response body being written to it cannot
be properly recycled in the connection pool
* incoming `DataBuffer` might not be released
This commit detects when `Void` types are asked as body types and in
those cases does the following:
1. Subscribe to the response body `Publisher` to allow the connection to
be returned to the connection pool
2. `cancel()` the body `Publisher` if the response body is not empty; in
that case, we choose to close the connection vs. consume the whole
response body
Those changes imply that `ClientHttpResponse` and other related
contracts don't need a `close()` method anymore.
Issue: SPR-16018
This commit moves WebFluxUriComponentsBuilder.fromServerRequest to the
ServerRequest interface itself.
Consequently, the WebFluxUriComponentsBuilder is removes itself, as it
contained no other methods.
Issue: SPR-15953
This commit introduces a methodName() method to the ServerRequest,
returning the String name of the method. This method is useful for
non-standard HTTP methods.
This commit introduces the following changes.
1) It adds a new Spring @NonNull annotation which allows to apply
@NonNullApi semantic on a specific element, like @Nullable does.
Combined with @Nullable, it allows partial null-safety support when
package granularity is too broad.
2) @Nullable and @NonNull can apply to ElementType.TYPE_USE in order
to be used on generic type arguments (SPR-15942).
3) Annotations does not apply to ElementType.TYPE_PARAMETER anymore
since it is not supported yet (applicability for such use case is
controversial and need to be discussed).
4) @NonNullApi does not apply to ElementType.FIELD anymore since in a
lot of use cases (private, protected) it is not part for the public API
+ its usage should remain opt-in. A dedicated @NonNullFields annotation
has been added in order to set fields default to non-nullable.
5) Updated Javadoc and reference documentation.
Issue: SPR-15756
Prior to this commit, various dependencies in the spring-test module
pulled in commons-logging as a transitive dependency. Consequently,
the presence of commons-logging in the generated Eclipse classpath
overrode the intended use of the spring-jcl module causing JUL to be
used instead of log4j for tests executed within Eclipse, thereby
ignoring the configuration in src/test/resources/log4j2-test.xml.
This commit addresses this issue by excluding commons-logging in
spring-test.gradle for all Selenium dependencies.
Issue: SPR-15930
Before this commit, there was no way to signal the HTTP client that we
were done consuming the response. Without that, the underlying client
library cannot know when it is safe to release the associated resources
(e.g. the HTTP connection).
This commit adds new `close()` methods on both `ClientHttpResponse`
and `ClientResponse`. This methods is non-blocking and its behavior
depends on the library, its configuration, HTTP version, etc.
At the `WebClient` level, `close()` is called automatically if we
consume the response body through the `ResponseSpec` or the
`ClientResponse` itself.
Note that it is *required* to call `close()` manually otherwise; not
doing so might create resource leaks or connection issues.
Issue: SPR-15920
This commit introduces a test that demonstrates that custom JUnit 4
rules can be @Autowired into a test instance but that they will not be
applied by JUnit since JUnit only ever sees such fields as null and
therefore ignores them.
Issue: SPR-15927
This commit applies the Dependency Management Plugin to modules that
require it; right now Spring Framework is importing BOMs for Netty and
Reactor dependencies only.
Instead of applying those BOMs to all modules, they're applied only
where they're needed.
Issue: SPR-15885
The main `build.gradle` file contains now only the common build
infrastructure; all module-specific build configurations have
been moved to their own build file.
Issue: SPR-15885
Includes general streamlining of dependency declarations with reduced version variables, direct use of EclipseLink 2.7 and its implicit JPA 2.2 dependency in spring-orm, mixed use of Hibernate 5.2.10 and 5.1.10 for integration tests, as well as an upgrade to Jetty 9.4.7 RC0 and a downgrade to Groovy 2.4.12 (since Groovy 2.5 won't be final in time for Spring Framework 5.0).
Issue: SPR-15879
Issue: SPR-15880
This commit restores and existing redirectedUrl and forwardedUrl
methods (simple String comparison) and creates separate
redirectedUrlTemplate and forwardedUrlTemplate methods that expand
and also encode before comparing.
Issue: SPR-15834
This commit revises the implementation of the SpringExtension to use
the getRequired*() methods in the ExtensionContext which are now built
into JUnit Jupiter thanks to inspiration from the initial "convenience"
methods implemented here.
This commit changes adds overloaded `ParameterizedTypeReference `
variants to body-related methods in `ServerRequest` and
`ServerResponse`.
It also adds a single PTR variant to ClientRequest, which was missing
before.
Issue: SPR-15817
This commit ensure that null-safety is consistent between
getters and setters in order to be able to provide beans
with properties with a common type when type safety is
taken in account like with Kotlin.
It also add a few missing property level @Nullable
annotations.
Issue: SPR-15792
This commit changes `ServerRequest.attribute(String)`` to return
`Optional<Object>` instead of `Optional<T>`, where `T` was infered
from a type parameter.
This commit makes the `uri` step of the WebTestClient optional, so that
users who have specified a base URL during WebClient config do not need
to provide an empty one (i.e. `url("")`).
Issue: SPR-15695
This commit introduces integration tests which verify that the
SpringExtension can be used in conjunction with JUnit Jupiter's
@ParameterizedTest support.
This commit introduces client-side request attributes, similar to those
found on the server-side. The attributes can be used, for instance, for
passing on request-specific information to a globally registered
ExchangeFilterFunction.
The client request builder, as well as WebClient.RequestHeadersSpec and
WebTestClient.RequestHeaderSpec, add methods for adding a single
attribute, as well as manipulating the entire attributes map.
The client request itself adds a accessor for the (immutable) attributes
map.
This commit also introduces a new variant of the basic authentication
filter in ExchangeFilterFunctions. This variant takes the username and
password from well-known attributes.
Issue: SPR-15691
This commit changes ServerRequest.queryParams from returning a
List<String> given a String name, to returning a
MultiValueMap<String, String>, which gives more flexibility.
This commit uses the newly introduced `PathContainer` and `RequestPath`
support in the functional web framework. It exposes the path container
as property in `ServerRequest`, and uses that in the path-based
`RequestPredicates`.
This commits extends nullability declarations to the field level, formalizing the interaction between methods and their underlying fields and therefore avoiding any nullability mismatch.
Issue: SPR-15720
The cloneBuilder helps to avoid the issue in the comment of the ticket.
Rather than creating the WebClient to then obtain a fresh builder which
causes connector instantiation, we now use the cloneBuilder
Issue: SPR-15674
This commit introduces 2 new public methods in HttpHeaders in order
to leverage Java 8 ZonedDateTime in addition to the existing long
(with GMT time zone implied) variants:
- ZonedDateTime getFirstZonedDateTime(String headerName)
- void setZonedDateTime(String headerName, ZonedDateTime date)
This commit also leverages Java 8 thread-safe DateTimeFormatter for
HttpHeader implementation instead of SimpleDateFormat. As a consequence
of the usage of DateTimeFormatter.RFC_1123_DATE_TIME, HTTP date header
serialization could change slightly for single digit days from for
example "Thu, 01 Jan 1970 00:00:00 GMT" to
"Thu, 1 Jan 1970 00:00:00 GMT".
Issue: SPR-15661
This commit replaces the WebClient.filter method with
WebClient.Builder.filter. The reason for this change is that filters
added via WebClient.filter would be applied in the opposite order of
their declaration, due to the compositional nature of the method,
combined with the immutable nature of the WebClient.
WebClient.Builder.filter does keep the order of the filters, as
registered.
Furthermore, this commit introduces a WebClient.mutate() method,
returning a WebClient.Builder. This method allow to add/remove filters
and other defaults from a given WebClient.
Issue: SPR-15657
Add WebClient.Builder.addFilter
Add Consumer-based headers and cookies methods to builders.
Add WebClient.mutate
This commit introduces LocaleContextResolver interface, which is used
at ServerWebExchange level to resolve Locale, TimeZone and other i18n
related informations.
It follows Spring MVC locale resolution patterns with a few differences:
- Only LocaleContextResolver is supported since LocaleResolver is less
flexible
- Support is implemented in the org.springframework.web.server.i18n
package of spring-web module rather than in spring-webflux in order
to be able to leverage it at ServerWebExchange level
2 implementations are provided:
- FixedLocaleContextResolver
- AcceptHeaderLocaleContextResolver
It can be configured with both functional or annotation-based APIs.
Issue: SPR-15036
This commit changes the use of `ResolvableType` to
`ParameterizedTypeReference` in all public-facing WebFlux APIs. This
change removes the necessity for providing the parameterized type
information twice: once for creating the `ResolvableType`, and once for
specifying a `BodyExtractor`.
Issue: SPR-15636
This commit also removes nullability from two common spots: ResolvableType.getType() and TargetSource.getTarget(), both of which are never effectively null with any regular implementation. For such scenarios, a non-null empty type/target is the cleaner contract.
Issue: SPR-15540
Beyond just formally declaring the current behavior, this revision actually enforces non-null behavior in selected signatures now, not tolerating null values anymore when not explicitly documented. It also changes some utility methods with historic null-in/null-out tolerance towards enforced non-null return values, making them a proper citizen in non-null assignments.
Some issues are left as to-do: in particular a thorough revision of spring-test, and a few tests with unclear failures (ignored as "TODO: NULLABLE") to be sorted out in a follow-up commit.
Issue: SPR-15540
This commit replaces the UnaryOperatory<ServerWebExchange> inputs with
Function<ServerWebExchange, ServerWebExchange> instead. Unfortunately
the composability methods inherited from Function don't work in terms
of generics for composing multiple UnaryOperator's.
Issue: SPR-15599
This commit introduces 2 new @Nullable and @NonNullApi
annotations that leverage JSR 305 (dormant but available via
Findbugs jsr305 dependency and already used by libraries
like OkHttp) meta-annotations to specify explicitly
null-safety of Spring Framework parameters and return values.
In order to avoid adding too much annotations, the
default is set at package level with @NonNullApi and
@Nullable annotations are added when needed at parameter or
return value level. These annotations are intended to be used
on Spring Framework itself but also by other Spring projects.
@Nullable annotations have been introduced based on Javadoc
and search of patterns like "return null;". It is expected that
nullability of Spring Framework API will be polished with
complementary commits.
In practice, this will make the whole Spring Framework API
null-safe for Kotlin projects (when KT-10942 will be fixed)
since Kotlin will be able to leverage these annotations to
know if a parameter or a return value is nullable or not. But
this is also useful for Java developers as well since IntelliJ
IDEA, for example, also understands these annotations to
generate warnings when unsafe nullable usages are detected.
Issue: SPR-15540
As a follow-up to the recent commit 246e72 some slight modifications
to MockServerExchangeMutator (renamed to ExchnageMutatorWebFilter).
Aside from the name change, the main difference is that "per request"
exchange processors are now simply applied via WebTestClient#filter(..).
Issue: SPR-15570
This commit replaces the option to bind the WebTestClient to an
HttpHandler to bind to a WebHandler instead.
This allows testing below the WebFlux level such as WebFilter,
WebHandler, or WebSession scenarios, but still a level above
HttpHandler so that WebTestClient is in charge of creating the
ServerWebExchange and expose consistently the
WebTestClient#MockServerSpec setup across all "mock" server bindToXxx
options.
Issue: SPR-15570
This commit factors ServerWebExchange mutator support out of
WebTestClient in favor of an independent public class called
MockServerExchangeMutator which implements WebFilter and can be
applied to the WebTestClient as any other WebFilter.
The MockServerExchangeMutator also exposes a method to apply
a client-side filter for "per request" mutators. See the Javadoc
of the MockServerExchangeMutator.
Issue: SPR-15570
This commit introduces a new method in HttpRequest:
`String getMethodValue`, which returns the HTTP method as a String.
Furthermore, HttpRequest.getMethod() has been given a default
implementation using this String value in combination with
`HttpMethod.resolve`.
Issue: SPR-15545
This commit removes the RouterFunctions.toHandlerMapping method, in
favor of native support for RouterFunctions in @EnableWebFlux
configuration classes.
In order to accomplish this, the HandlerStrategies components has been
repurposed to only be used for the "bare-bones" HttpHandler, while the
(newly introduced) RouterFunctionMapping uses the strategies as exposed
through WebFluxConfigurationSupport.
Furthermore, this commit also introduces support for testing
RouterFunctions without resorting to an application context.
Issue: SPR-15536
With this commit, ServerCodecConfigurer is now exposed as a bean in
order to be provided to DefaultServerWebExchange via
WebHttpHandlerBuilder and HttpWebHandlerAdapter. This allows
DefaultServerWebExchange to get configured codecs for reading form or
multipart requests.
Issue: SPR-14546
According to RFC-6265 that there should be a space between the ; and
the attribute name, i.e. the header should be something like
name=value; Domain=localhost; HttpOnly rather than
name=value;Domain=localhost;HttpOnly
Issue: SPR-15225
This commit renames the `body(Object)` on ServerResponse to
`syncBody(Object)`. The reason for this is that the original method
name clashed with the `body(Publisher)` method in the Kotlin extension.
The new name nicely reflects the synchronous nature of the method,
making it less appealing than the `Publisher`-based `body` method.
Issue: SPR-15467
This commit makes changes to WebClient and WebTestClient in oder to
limit setting the body according to HTTP method and also to facilitate
providing the request body as Object.
Specifically, this commit:
- Moves methods that operate on the request body to a RequestBodySpec
in both WebClient and WebTestClient, and rename them to `body`.
These methods now just *set* the body, without performing
an exchange (which now requires an explicit exchange call).
- Parameterizes UriSpec in both WebClient and WebTestClient, so that
it returns either a RequestHeadersSpec or a RequestBodySpec.
Issue: SPR-15394
This commit deprecates `AsyncRestTemplate` and related types
(`AsyncClientHttpRequestFactory` etc.) in favor of the Spring 5.0
`WebClient`.
Issue: SPR-15294
This commit folds ServerHttpMessage[Reader|Writer] into its parent
HttpMessage[Reader|Writer] with the server methods pre-implemented
by default to be simple pass-through delegates.
This commit changes the `MediaTypeFactory` to return
`Optional<MediaType>` (instead of a plain `MediaType`) for the
`getMediaType` methods.
Issue: SPR-14908
This commit changes the `MockServletContext.getMimeType` method to use
`MediaTypeFactory` instead of JAF. It also adds a `addMimeType(String,
MediaType)` method to customize the mime types returned from said
method.
Issue: SPR-14908
ExchangeMutatorWebFilter now supports multiple mutator registrations
for the same request header id by creating a single composed function.
Issue: SPR-15250
This commit adds a common base class for server-less setup with the
option to configure a transformation function on the
ServerWebExchange for every request.
The transformation is applied through a WebFilter. As a result the
RouterFunction setup is now invoked behind a DispatcherHandler with
a HandlerMapping + HandlerAdapter.
Issue: SPR-15250
Currently the BOM versions are:
* reactor-core 3.0.6.BUILD-SNAPSHOT
* reactor-netty 0.6.2.BUILD-SNAPSHOT
This commit fixes as well a few deprecations in reactor-core.
The WebTestClient API no longer provides access to a base
ExchangeResult without a decoded response body.
Instead the response has to be decoded first and tests can then
access the EntityExchangeResult and FluxExchangeResult sub-types.
The WiretapConnector now decorated the ClientHttpRequest & Response
in order to intercept and save the actual content written and read.
The saved content is now incorporated in the diagnostic output but may
be used for other purposes as well (e.g. REST Docs).
Diagnostic information about an exchange has also been refactored
similar to command line output from curl.
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.
This commit polishes previous one by also accepting
generic types explicitly declared with a class that
extends DataBuffer allowing to write Flux<DefaultDataBuffer>
for example.
Issue: SPR-14952
This modifies the signature of
ReactiveHttpOutputMessage#writeAndFlush(...) in order to
be able to use Flux<Flux<DataBuffer>> objects as arguments of
this method.
Issue: SPR-14952
This commit introduces the `DispatcherServletCustomizer` callback
interface that can be used to customize the `DispatcherServlet` that a
`MockMvc` is using.
Previously, only the `dispatchOptions` flag can be customized. This
commit allows to customize any property of `DispatcherServlet` before it
is initialized.
Issue: SPR-14277
Prior to this commit, when using @EnabledIf or @DisabledIf in Spring's
JUnit Jupiter support, the test's ApplicationContext was always eagerly
loaded, even if the ApplicationContext would never be used (i.e., the
test was disabled). This behavior can lead to undesirable side effects
-- for example, attempting to load an application context that requires
services only available on the CI server when the test is not actually
running on the CI server.
This commit addresses this issue by introducing new boolean
`loadContext` flags in @EnabledIf and @DisabledIf. By default these
flags are set to false which means that the user's test application
context will not be loaded to evaluate the expression. On the contrary,
a dummy application context will be loaded instead, and expressions
will be evaluated against that dummy context. Consequently, if the user
wishes to interact with properties from the Spring Environment or with
beans from the test application context, the `loadContext` must be
explicitly set to true.
In addition, expressions which evaluate to a String must now evaluate
to exactly "true" or "false" (ignoring case and surrounding whitespace).
Issue: SPR-14649
String with version 5 the name of Java Platform, Enterprise Edition
changed from J2EE to Java EE. However a lot of the documentation still
uses the term J2EE.
This commit includes the following changes:
* replace J2EE with Java EE where appropriate
This is not a blind search and replace. The following occurrences
remain unchanged:
* references to old J2EE releases, most notably 1.3 and 1.4.
* references to "Expert One-On-One J2EE Design and Development"
* references to "Core J2EE patterns"
* XML namespaces
* package names
Issue: SPR-14811
See gh-1206
Prior to this commit, the redirectedUrl() and forwardedUrl() methods in
MockMvcResultMatchers supported fully constructed URLs and URLs
containing Ant-style path patterns. However, URI templates were not
supported for these result matchers even though the request path can be
built using URL templates -- for example, via the get() and post()
methods in MockMvcRequestBuilders.
This commit addresses this shortcoming by allowing users to supply a
URL template instead of a fully constructed URL to redirectedUrl() and
forwardedUrl(). To populate the URL template, template variables may be
supplied to redirectedUrl() and forwardedUrl() as var-args.
Issue: SPR-14790
Commit e65a1a4372 introduced support in PrintingResultHandler for only
printing the request or response body in the Spring MVC Test framework
if the content type is known to be text-based (e.g., plain text, HTML,
XHTML, XML, JSON, etc.). For unknown content types the body is assumed
to be text-based and is therefore always printed. The latter behavior,
however, is undesirable since the content may in fact not be text-based.
This commit addresses this issue by making the printing of the request
or response body an opt-in feature. Specifically, if a character
encoding has been set, the request or response body will be printed by
the PrintingResultHandler. Note, however, that the character encoding
is set to ISO-8859-1 in MockHttpServletResponse by default.
In addition, MockHttpServletRequest's getContentAsString() method now
throws an IllegalStateException if the character encoding has not been
set.
Issue: SPR-14776
Prior to this commit, PrintingResultHandler always printed the request
or response body regardless of its content type. For binary content,
however, the output was unreadable and therefore useless.
This commit addresses this issue by only printing the request or
response body if it is "printable" (i.e., if its content type is known
to be text-based such as plain text, HTML, XHTML, XML, JSON, etc.). If
the content type is unknown (e.g., unspecified for the HTTP request in
the test), it is assumed that the body is printable.
Issue: SPR-14776
Prior to this commit, the PrintingResultHandler used by the various
print() and log() methods in Spring MVC Test printed the response body
but not the request body.
Since request bodies are sometimes generated programmatically, however,
it can be beneficial to have the dynamically generated request body
logged as well.
This commit therefore prints the request body in PrintingResultHandler
by delegating to the recently introduced getContentAsString() method in
MockHttpServletRequest.
Issue: SPR-14717
In order to improve debugging and logging within test suites, this
commit introduces getContentAsByteArray() and getContentAsString()
methods in MockHttpServletRequest, analogous to the existing methods in
MockHttpServletResponse.
Issue: SPR-14717
Whereas the existing TestContextConcurrencyTests verify support for
concurrency in the TestContextManager and TestContext, this commit
introduces SpringJUnit4ConcurrencyTests that verify support for
concurrent test execution in Spring's JUnit 4 support, namely in the
SpringRunner, SpringClassRule, and SpringMethodRule.
The tests executed by this new test class come from a hand-picked
collection of test classes within the test suite that is intended to
cover most categories of tests that are currently supported by the
TestContext Framework on JUnit 4.
Note, however, that the chosen test classes intentionally do not
include any classes that fall under the following categories.
- tests that make use of Spring's @DirtiesContext support
- tests that make use of JUnit 4's @FixMethodOrder support
- tests that commit changes to the state of a shared in-memory database
Issue: SPR-5863
This commit improves the exception message thrown when a test's
ApplicationContext is no longer active by explaining that the cause
may be due to parallel test execution.
Issue: SPR-5863
Prior to this commit, executing tests concurrently in the TestContext
Framework (TCF) was unsupported and typically lead to unpredictable
results.
This commit addresses this core issue by supporting concurrent
execution in the TestContextManager and the DefaultTestContext.
Specifically, the TestContextManager now uses ThreadLocal storage for
the current TestContext, thereby ensuring that any registered
TestExecutionListeners and the TestContextManager itself operate on a
TestContext specific to the current thread.
In order to avoid repeatedly incurring the costs of the overhead of the
TCF bootstrapping process, the original TestContext built by the
TestContextBootstrapper is used as a template which is then passed to
the copy constructor of the concrete implementation of the TestContext
to create the context for the current thread. DefaultTestContext now
implements such a copy constructor, and all concrete implementations of
TestContext are encouraged to do the same.
If the TestContext built by the TestContextBootstrapper does not
provide a copy constructor, thread-safety and support for concurrency
are left completely to the implementation of the concrete TestContext.
Note, however, that this commit does not address any thread-safety or
concurrency issues in the ContextLoader SPI or its implementations.
Issue: SPR-5863
This commit inlines the basic implementation of AttributeAccessorSupport
and converts the LinkedHashMap to a ConcurrentHashMap.
In addition, attributes are now included in toString().
Issue: SPR-5863