This commit moves the features of MockHttpServletRequestBuilder in
an abstract class so that another class can offer the same feature
whilst providing AssertJ support. This wasn't possible previously as
the builder's return type would lose the concrete builder types.
This change benefits MockMultipartHttpServletRequestBuilder that can
use the same mechanism to offer additional settings.
This change also makes it so that a builder instance can be created
using only the HttpMethod. Previously, the URI had to be provided as
well and that makes it impossible to specify it using the builder.
See gh-32913
Previously, AbstractJsonContentAssert worked on a raw String, which
made standard AssertJ nested calls, such as satisfies, to return an
assert on the raw string, rather than one with JSON support.
This commit rework AbstractJsonContentAssert so that it no longer
extend from AbstractStringAssert. This makes the list of methods more
focused on JSON assertions, and allow standard operations to provide
the right assert object.
Closes gh-32894
This commit makes several improvements to MultiValueMap:
- asSingleValueMap offers a single-value view (as opposed to the
existing toSingleValueMap, which offers a copy)
- fromSingleValue is a static method that adapts a Map<?,?> to the
MultiValueMap interface
- fromMultiValue is a static method that adapts a Map<?,List<?>> to the
MultiValueMap interface
Closes gh-32832
This commit introduces a JsonComparator abstraction, with an
implementation using JSONAssert. Previously, JSONAssert was the only
choice.
Test APIs have been adapted to allow the new abstraction while relying
on JSONAssert still for high-level methods.
Closes gh-32791
Co-authored-by: Stéphane Nicoll <stephane.nicoll@broadcom.com>
This commit changes the FormHttpMessageConverter from a
HttpMessageConverter<MultiValueMap<String, ?>> to a
HttpMessageConverter<Map<String, ?>>, so that normal, single-value maps
can also be used as form representation, both for reading and writing.
Closes gh-32826
Prior to this commit, as a result of commit 6cdb34410b, the
DynamicValuesPropertySource was eagerly registered in the Environment
even if the DynamicPropertyRegistry was never used to register dynamic
properties.
This commit ensures that the DynamicValuesPropertySource is only
registered if we know that the DynamicPropertyRegistry is actually used
-- either by a @DynamicPropertySource method in a test class or via a
bean in the ApplicationContext that invokes add() on the
DynamicPropertyRegistry bean.
See gh-32271
Closes gh-32871
This commit uses the bean factory `isAutowiredCandidate` method directly
in `BeanOverrideBeanFactoryPostProcessor` to select a single match among
multiple candidates when matching by type.
The expected consequence, in most cases, is that this will delegate to
a `@Qualifier`-aware `QualifierAnnotationAutowireCandidateResolver`.
In that sense, bean overriding by-type matching is now potentially
taking Qualifier annotations or meta-annotations into account.
It also changes the way existing bean definitions are checked in case
a bean name has been specified: factory beans are now taken into account
when checking the type of an existing definition matches the expected
bean override type.
Closes gh-32822
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.