Prior to this commit (and since Spring Framework 5.0), Spring's
integration with JUnit Jupiter supported detection of test
configuration (e.g., @ContextConfiguration, etc.) on @Nested classes.
However, if a @Nested class did not declare its own test configuration,
Spring would not find the configuration from the enclosing class. This
is in contrast to Spring's support for automatic inheritance of test
configuration from superclasses. The only workaround was to
copy-n-paste the entire annotation configuration from enclosing classes
to nested tests classes, which is cumbersome and error prone.
This commit introduces a new @NestedTestConfiguration annotation that
allows one to choose the EnclosingConfiguration mode that Spring should
use when searching for test configuration on a @Nested test class.
Currently, the options are INHERIT or OVERRIDE, where the current
default is OVERRIDE. Note, however, that the default mode will be
changed to INHERIT in a subsequent commit. In addition, support will be
added to configure the global default mode via the SpringProperties
mechanism in order to allow development teams to revert to the behavior
prior to Spring Framework 5.3.
As of this commit, inheritance of the following annotations is honored
when the EnclosingConfiguration mode is INHERIT.
- @ContextConfiguration / @ContextHierarchy
- @ActiveProfiles
- @TestPropertySource / @TestPropertySources
- @WebAppConfiguration
- @TestConstructor
- @BootstrapWith
- @TestExecutionListeners
- @DirtiesContext
- @Transactional
- @Rollback / @Commit
This commit does NOT include support for inheriting the following
annotations on enclosing classes.
- @Sql / @SqlConfig / @SqlGroup
In order to implement this feature, the search algorithms in
MetaAnnotationUtils (and various other spring-test internals) have been
enhanced to detect when annotations should be looked up on enclosing
classes. Other parts of the ecosystem may find the new
searchEnclosingClass() method in MetaAnnotationUtils useful to provide
similar support.
As a side effect of the changes in this commit, validation of user
configuration in repeated @TestPropertySource declarations has been
removed, but this may be reintroduced at a later date.
Closes gh-19930
The exchange() method is now deprecated because it is not safe for
general use but that doesn't apply to the WebTestClient because it
exposes a different higher level API for response handling that
ensures the response is consumed. Nevertheless WebTestClient cannot
call WebClient.exchange() any more.
To fix this WebTestClient no longer delegates to WebClient and thus
gains direct access to the underlying ExchangeFunction. This is
not a big deal because WebClient and WebTestClient do the same
only when it comes to gathering builder options and request input.
See gh-25751
Prior to this commit, some tests would belong to the PERFORMANCE
`TestGroup`, while they were not testing for performance but rather
performing functional tests that involve long running operations or
timeouts.
This commit moves those tests to the LONG_RUNNING `TestGroup`.
See gh-24830
UrlPathHelper is often created and used without customizations or with
the same customizations. This commit introduces re-usable, instances.
Effectively a backport of commit 23233c.
See gh-25690
This commit makes several changes in both WebMvc.fn as well as
WebFlux.fn.
- ServerRequest now exposes a RequestPath through requestPath(), and
pathContainer() has been deprecated.
- The PathPredicate and PathResourceLookupFunction now respects this
RequestPath's pathInApplication() in their path-related
functionality.
- When nesting, the PathPredicate now appends the matched part of the
path to the current context path, instead of removing the matched
part (which was done previously). This has the same result: the
matched part is gone, but now the full path stays the same.
Closes gh-25270
Provides parity with similar options in MockMvc:
- compare header using a long value
- compare header using a date/time value
- dedicated method for "Location" header (redirect)
- let Hamcrest assert a header even when missing
See gh-19647
WebTestClient is an actual client and generally it's only possible
to assert the client response (i.e. what goes over HTTP). However,
in a mock server scenario technically we have access to the server
request and response and can make those available for further
assertions.
This will be helpful for the WebTestClient integration with MockMvc
where many more assertions can be performed on the server request
and response when needed.
See gh-19647
The original behavior was to ignore the body which came with odd
warnings in the Javadoc and potential leaks that could be reported
from tests causing unnecessary concern.
This change causes the body to be released and effectively still
ignores it but minus the potential leaks.
See gh-19647
The claimRequest method was not intended to be public and couldn't
have been used since the Info type it returned was package private.
This change completely hides the Info.
See gh-19647
Prior to this commit it was possible to configure the
DefaultListableBeanFactory used by the GenericApplicationContext
created by AbstractGenericContextLoader, but it was not possible to
completely replace the bean factory.
This commit introduces a new createContext() factory method in
AbstractGenericContextLoader which indirectly allows subclasses to
supply a custom DefaultListableBeanFactory implementation to the
GenericApplicationContext.
Closes gh-25600
This commit declares each of the following public interfaces as a
@FunctionalInterface.
- org.springframework.context.ApplicationContextInitializer
- org.springframework.test.web.servlet.DispatcherServletCustomizer
- org.springframework.validation.MessageCodeFormatter
- org.springframework.util.IdGenerator
- org.springframework.beans.factory.config.YamlProcessor.MatchCallback
- org.springframework.beans.factory.config.YamlProcessor.DocumentMatcher
Closes gh-25580
Prior to this commit, MockHttpServletResponse's setCharacterEncoding()
method did not update the contentType property, which violates the
Servlet 2.4 Javadoc for getContentType() and setCharacterEncoding().
This commit addresses this issue; however, some existing tests may have
to be updated as a result of this change.
For example, note how some of the tests in this commit have been
refactored to use MediaType##isCompatibleWith() instead of asserting
exact matches for the value returned by MockHttpServletResponse's
getContentType() method.
Closes gh-25536
Since Spring Framework 5.2, @RestControllerAdvice registered with
MockMvc when using MockMvcBuilders.standaloneSetup() has no longer been
properly supported if annotation attributes were declared in the
@RestControllerAdvice annotation. Prior to 5.2, this was not an issue.
The cause for this regression is two-fold.
1. Commit 50c257794f refactored
DefaultListableBeanFactory so that findAnnotationOnBean() supports
merged annotations; however, that commit did not refactor
StaticListableBeanFactory#findAnnotationOnBean() to support merged
annotations.
2. Commit 978adbdae7 refactored
ControllerAdviceBean so that a merged @ControllerAdvice annotation
is only looked up via ApplicationContext#findAnnotationOnBean().
The latter relies on the fact that findAnnotationOnBean() supports
merged annotations (e.g., @RestControllerAdvice as a merged instance of
@ControllerAdvice). Behind the scenes, MockMvcBuilders.standaloneSetup()
creates a StubWebApplicationContext which internally uses a
StubBeanFactory which extends StaticListableBeanFactory. Consequently,
since the implementation of findAnnotationOnBean() in
StaticListableBeanFactory was not updated to support merged annotations
like it was in DefaultListableBeanFactory, we only see this regression
with the standalone MockMvc support and not with MockMvc support for an
existing WebApplicationContext or with standard Spring applications
using an ApplicationContext that uses DefaultListableBeanFactory.
This commit fixes this regression by supporting merged annotations in
StaticListableBeanFactory#findAnnotationOnBean() as well.
Closes gh-25520
Prior to this commit, if a value existed at the specified JSON path but
had an incompatible type, the AssertionError thrown contained a message
stating that the value did not exist (i.e., "No Value at JSON Path"),
which was not only misleading but also technically incorrect.
This commit fixes the error message for such use cases. For example, the
AssertionError thrown in such use cases now resembles the following.
At JSON path "$.name", value <Lisa> of type <java.lang.String> cannot
be converted to type <byte[]>
Closes gh-25480
Prior to this commit, calling reset() on MockHttpServletResponse did not
reset the `charset` field to `false` which could result in the
"Content-Type" header containing `;charset=null` which in turn would
result in errors when parsing the "Content-Type" header.
This commit resets the charset field to `false` in
MockHttpServletResponse's reset() method to avoid such errors.
Closes gh-25501