This commit avoids several instances of MockHttpServletRequest to
have a common reader for empty content as closing it will have an
unwanted side effect on the others.
Closes gh-32820
Prior to this commit, DynamicPropertyRegistry could only be used with a
static @DynamicPropertySource method in an integration test class;
however, it can also be useful to be able to register a "dynamic
property" from within a test's ApplicationContext -- for example, in a
@Bean method in a @Configuration class that is specific to testing
scenarios.
To support such use cases, this commit updates the dynamic property
source infrastructure so that a DynamicPropertyRegistry is always
registered as a singleton bean in a test's ApplicationContext. This
allows DynamicPropertyRegistry to be autowired into a @Configuration
class or supplied to a @Bean method as an argument as shown in the
following example.
@Bean
@DynamicPropertySource
ApiServer apiServer(DynamicPropertyRegistry registry) {
ApiServer apiServer = new ApiServer();
registry.add("api.url", apiServer::getUrl);
return apiServer;
}
Note that the use of @DynamicPropertySource on the @Bean method is
optional and results in the corresponding bean being eagerly
initialized so that other singleton beans in the context can be given
access to the dynamic properties sourced from that bean when those
other beans are initialized.
Side note: DynamicPropertySourceBeanInitializer temporarily implements
LoadTimeWeaverAware since doing so is currently the only way to have a
component eagerly initialized before the
ConfigurableListableBeanFactory.preInstantiateSingletons() phase.
However, we plan to introduce a first-class callback to support such
use cases in the future.
Closes gh-32271
This commit introduces a `isNotEqualTo(String)` assertion in order to
avoid false negatives when using the default Object-based assertion.
This is a risk since MediaTypeAssert has a `isEqualTo(String)` method
that overrides the base object method and parses the provided String
into a MediaType. Users may thus be tempted to use the reverse assertion
and expect the same parsing behaviour.
This commit also adds tests around the String parsing and the isNotEqual
cases.
Closes gh-32756
This change switches default behavior of `@TestBean`, `@MockitoBean` and
`@MockitoSpyBean` to match the bean definition / bean to override by
type in the case there is no explicit bean name provided via the
annotation. The previous behavior of using the annotated field's name
is still an option for implementors, but no longer the default.
Closes gh-32761
Prior to this commit, trailing slash matching was disabled by default in
Spring MVC with gh-28552. `StandaloneMockMvcBuilder` was not changed as
a result and still had the trailing slash match option enabled.
This commit aligns the defaults in `StandaloneMockMvcBuilder` to better
reflect the expected behavior in tests.
Closes gh-32796
This commit renames AssertableMockMvc to MockMvcTester as the former
was too mouthful, and we are looking for a naming pattern that can be
applied consistently to test utilities that rely on AssertJ.
Rather than AssertableMvcResult, we now use MvcTestResult and it no
longer extends from MvcResult itself. That avoids having existing code
that is migrated to the new API whilst assigning the result to MvcResult
and get a bad DevXP as that doesn't bring any of the AssertJ support.
See gh-32712
This commit removes ResponseBodyAssert and rather offers first-class
access support for the response body at the root level using bodyText(),
bodyJson(), and body().
This avoids a double navigation to assert the response body.
See gh-32712
This commit merges the JSONCompare and JsonPath support in a single
assert object. The rationale for the previous situation was that
JsonPath is optional but merging the assertions methods do not make
it mandatory as the usage if JsonPath is triggered only if it is
actually used.
See gh-32712
Previously, if a factory method is defined on a parent, the generated
code would blindly use the method's declaring class for both the target
of the generated code, and the signature of the method.
This commit improves the resolution by considering the factory metadata
in the BeanDefinition.
Closes gh-32609
This commit improves on the bean overriding feature in several ways:
the API is simplified and polished (metadata and processor contracts,
etc...).
The commit also reworks infrastructure classes (context customizer,
test execution listener, BeanOverrideBeanFactoryPostProcessor, etc...).
Parsing of annotations is now fully stateless.
In order to avoid OverrideMetadata in bean definition and to make a
first step towards AOT support, the BeanOverrideBeanFactoryPostProcessor
now delegates to a BeanOverrideRegistrar to track classes to parse,
the metadata-related state as well as for the field injection methods
for tests.
Lastly, this commit increases the test coverage for the provided
annotations and adds integration tests and fixes a few `@TestBean`
issues.
This commit makes the use of bean definition overriding more visible and
prepare for a deprecation of the feature in the next major release.
As of this commit, use of bean definition overriding logs at INFO level.
The previous log level can be restored by setting the
allowBeanDefinitionOverriding flag explicitly on the BeanFactory (or
via the related ApplicationContext).
A number of tests that are using bean overriding on purpose have been
updated to set this flag, which will make them easier to find once we
actually deprecate the feature.
Closes gh-31288
The ApplicationContext has a resource cache that it uses while the
context is being refreshed. Once the refresh phase completes, the
cache is cleared as its content is no longer in use. If beans are
lazily initialized, there is a case where the cache might be filled
again as processing is deferred past the refresh phase.
For those cases, the cache is not cleared. This can be a problem when
running in this mode with a large set of test configurations as the TCF
caches the related contexts.
This commit includes an additional TestExecutionListener to the TCF that
clears the resource cache if necessary once a test class completes. It
is ordered so that it runs after `@DirtiesContext` support as marking
the context as dirty will remove it from the cache and make that extra
step unnecessary.
Closes gh-30954
This commit adds a new way to use MockMvc by returning a MvcResult that
is AssertJ compatible. Compared to the existing MockMvc infrastructure,
this new model has the following advantages:
* Can be created from a MockMvc instance
* Dedicated builder methods for easier setup
* Assertions use familiar AssertJ syntax with discoverable assertions
through a DSL
* Improved exception message
See gh-21178
Co-authored-by: Brian Clozel <brian.clozel@broadcom.com>
This commit adds AssertJ compatible assertions for HTTP request and
responses, including headers, media type, and response body. The latter
delegate to the recently included JSON assert support.
See gh-21178
Historically, we have rarely intentionally thrown a
NullPointerException in the Spring Framework. Instead, we prefer to
throw either an IllegalArgumentException or IllegalStateException
instead of a NullPointerException.
However, changes to the code in recent times have introduced the use of
Objects.requireNonNull(Object) which throws a NullPointerException
without an explicit error message.
The latter ends up providing less context than a NullPointerException
thrown by the JVM (since Java 14) due to actually de-referencing a
null-pointer. See https://openjdk.org/jeps/358.
In light of that, this commit revises our current use of
Objects.requireNonNull(Object) by removing it or replacing it with
Assert.notNull().
However, we still use Objects.requireNonNull(T, String) in a few places
where we are required to throw a NullPointerException in order to
comply with a third-party contract such as Reactive Streams.
Closes gh-32430
This commit upgrades to a major new release of HtmlUnit. This is a
breaking change as HtmlUnit 3 moves to a `org.htmlunit` package and
calling code needs to be restructured.
Our use of Selenium has been adapted accordingly, moving to Selenium
3, using the new org.seleniumhq.selenium:htmlunit3-driver integration.
Closes gh-30392
This commit introduces two sets of annotations (`@TestBean` on one side
and `MockitoBean`/`MockitoSpyBean` on the other side), as well as an
extension mecanism based on the `@BeanOverride` meta-annotation.
Extension implementors are expected to only provide an annotation,
a BeanOverrideProcessor implementation and an OverrideMetadata subclass.
Closes gh-29917.
Add helpers to CollectionUtils for building HashSets and LinkedHashSets
that can hold an expected number of elements without needing to
resize/rehash.
Closes gh-32291
This commit removes the previous implementation in favor of the new
PlaceholderParser. The only noticeable side effect is that the exception
is no longer an IllegalArgumentException, but rather the dedicated
PlaceholderResolutionException.
See gh-9628
This commit improves jsonpath support in WebTestClient by detecting
a suitable json encoder/decoder that can be applied to assert more
complex data structure.
Closes gh-31653
This commit improves JsonPathExpectationsHelper to allow a custom json
path configuration to be defined. The primary objective of a custom
configuration is to specify a custom mapper that can deserialize complex
object structure.
As part of this commit, it is now possible to invoke a Matcher against
a type that holds generic information, using a regular
ParameterizedTypeReference.
Given that the existing constructor takes a vararg of Object, this
commit also deprecates this constructor in favor of formatting the
expression String upfront.
Closes gh-31651
This commit updates ContentRequestMatchers#multipartData
Javadoc to mention Tomcat fork of Commons FileUpload library
instead of the original variant.
It also adds a similar note to
ContentRequestMatchers#multipartDataContains.
Closes gh-31988
This commit adds Javadoc to the `getContentLength` method of
`MockHttpServletResponse` to reflect that it gets its value from the
HTTP response header.
Closes gh-31833
Search for : assertThat\((.+).isEmpty\(\)\).isTrue\(\)
Replace with : assertThat($1).isEmpty()
Search for : assertThat\((.+).isEmpty\(\)\).isFalse\(\)
Replace with : assertThat($1).isNotEmpty()
Closes gh-31758
Search for : assertThat\((.+)\.contains\((.+)\)\)\.isTrue\(\)
Replace with : assertThat($1).contains($2)
Search for : assertThat\((.+)\.contains\((.+)\)\)\.isFalse\(\)
Replace with : assertThat($1).doesNotContain($2)
Closes gh-31762
This commit moves the condition used by `@DisabledInAotMode` to a
concrete implementation rather than using `@DisabledIf` as it causes
build initialization in a native image.
Closes gh-31705
Prior to this commit, the TestContextManager logged an exception from a
TestExecutionListener at WARN level except in prepareTestInstance()
where such an exception was logged at ERROR level (except for a skipped
exception which is logged at INFO level).
For consistency, this commit modifies TestContextManager so that it
always logs non-skipped exceptions from TestExecutionListeners at WARN
level.
Closes gh-31688
Prior to this commit, any time an aborted/skipped exception was thrown
by a TestExecutionListener, the TestContextManager unconditionally
logged the exception at WARN level -- or ERROR level for
prepareTestInstance() callbacks.
Regarding the latter, an aborted/skipped exception is certainly not an
ERROR, and in general the associated log output is very verbose
(including a stack trace) and not something the user should be warned
about it.
To improve the user experience, this commit revises TestContextManager
so that it logs such exceptions at INFO level.
Specifically, the following types of exceptions are considered
aborted/skipped exceptions.
- JUnit Jupiter: org.opentest4j.TestAbortedException
- JUnit 4 org.junit.AssumptionViolatedException
- TestNG: org.testng.SkipException
Closes gh-31479
This commit clarifies that the annotation is used to capture events that
are fired from the test `Thread` or descendant threads, since the test
framework uses `InheritableThreadLocal` to store captured events now.
See gh-31079
See gh-30020