Prior to this commit, SSE support in Spring would write payloads with
the "data:" prefix (without space). While this is OK with the standard,
this makes it harder for implementations to support reading and writing
payloads with Spring (the round trip use case).
This commit introduces a breaking change and now enforces "data: " in
all variants. This has the potential of breaking some low level test
suites with text/plain or custom media types, but this should overall
make the situation better for developers.
Closes gh-37242
The static SimpleDateFormat instance in
AbstractMockHttpServletRequestBuilder is shared across all
instances. SimpleDateFormat.format() mutates internal Calendar
state and is not thread-safe, which can produce corrupt date
strings or ArrayIndexOutOfBoundsException when tests run in
parallel.
Replace with DateTimeFormatter which is immutable and thread-safe.
Signed-off-by: Sebastien Tardif <SebTardif@ncf.ca>
MockMvcResultMatchers.forwardedUrl() already accepts a @Nullable
expected value to assert that no forwarding occurred, but its
counterpart redirectedUrl() previously did not, even though the
underlying assertEquals() comparison is null-safe and behaves the same
way for redirects.
To address that, this commit adds the same @Nullable declaration to
redirectedUrl() and documents the null semantics in the Javadoc for
both methods.
Closes gh-37230
FlashMap.startExpirationPeriod(int) and MockMvcWebConnection's cookie
handling both multiplied an int number of seconds by 1000 without
widening to long. Above 2_147_483 seconds (about 24.9 days) the
multiplication overflows to a negative offset, so the computed
expiration time lands in the past.
For FlashMap, a flash map configured through
AbstractFlashMapManager.setFlashMapTimeout(int) with a large timeout is
then treated as expired immediately. For MockMvcWebConnection, a cookie
with a large max-age is removed from the CookieManager instead of being
stored.
This applies the same widening already used for this pattern in
gh-25613.
Closes gh-37208
Signed-off-by: kogun <akogun@gmail.com>
This commit picks up where 97067f9c9c left off by removing the four
trailing collection-clearing calls in clear(), which are now redundant
since the removal loop already empties contextMap, hierarchyMap,
contextUsageMap, and unusedContexts as an invariant. This commit also
adds regression tests in LruContextCacheTests for closing a context
hierarchy via clear() and reset(), asserting bottom-up close order with
Mockito.inOrder(), and confirming that getParentContextCount() and
getContextUsageCount() return to zero.
See gh-36825
This updates the TestContext Framework cache so that clearing the
cache also closes cached ConfigurableApplicationContext instances
instead of only dropping the internal references. The implementation
reuses the existing removal path, preserving the hierarchy-aware close
behavior already used by cache eviction/removal.
The ContextCache contract now documents the close behavior for
clear(), and LruContextCacheTests covers both clear() and reset(),
since reset() delegates to clear().
See gh-26196
Closes gh-36825
Signed-off-by: Will-thom <116388885+Will-thom@users.noreply.github.com>
HtmlUnit 5 moved its Cookie type to org.htmlunit.http, so
Spring Test's HtmlUnit integration now uses the new API.
Constraint: Keep HtmlUnit and htmlunit3-driver versions compatible.
Rejected: Upgrade HtmlUnit alone | driver requires HtmlUnit 5.4.0.
Confidence: high
Scope-risk: narrow
Directive: Keep HtmlUnit and the driver version aligned.
Tested: JAVA_HOME=/opt/homebrew/opt/openjdk@25 ./gradlew build
Not-tested: None
Signed-off-by: jungh8n <jh981113@naver.com>
Prior to this commit,
`MockHttpServletRequest.isRequestedSessionIdValid()` would return `true`
by default and could only be changed manually with a setter. This does
not align with the Servlet spec because of 1) its default value and 2)
it does not react to `changeSessionId()` calls.
This commit fixes that behavior while still allowing "manual" booleans
being set here.
Fixes gh-36631
This commit documents how the Bean Override support in the TestContext
framework interacts with Spring AOP proxies created for annotations
such as @Transactional, @Cacheable, and @Retryable.
The new "Bean Overrides and Spring AOP Proxies" section in the general
Bean Overriding documentation explains that overrides using the WRAP
strategy (such as @MockitoSpyBean) end up as the target of any AOP
proxy subsequently created for the original bean; whereas, overrides
using the REPLACE or REPLACE_OR_CREATE strategy (such as @TestBean,
@MockitoBean) bypass the container's bean post-processing entirely and
therefore carry no AOP advice at all.
The new "@MockitoSpyBean and Spring AOP Proxies" section documents the
resulting stubbing and verification semantics. Verification via
Mockito's verify() API works transparently regardless of whether it is
invoked on the proxy or on the spy. Stubbing via doReturn(...)/doThrow(...)
is safe for stateless advice such as @Retryable, but can silently
corrupt the spy's configured answers for stateful or memoizing advice
such as @Cacheable, since the invocation used to declare a stub is
intercepted by Mockito before it reaches the spy and returns an empty
value that such advice may then cache.
AopTestUtils.getUltimateTargetObject(...) is documented as the way to
stub directly against the spy in that case.
The same section also documents how to disable the AOP advice for a
test altogether while leaving it in place in production code – for
example, binding a @Retryable attribute to a property placeholder
overridden via @TestPropertySource, or replacing the CacheManager with
a NoOpCacheManager via @TestBean.
Brief cross-referencing notes have also been added to the @TestBean
documentation and to the existing AopTestUtils description in the
"General Testing Utilities" section, to avoid duplicating the
explanation across pages.
In addition, the Javadoc for @MockitoSpyBean now contains a concise
WARNING summarizing these AOP proxy implications and linking to the new
reference documentation section for details.
Closes gh-37121
Following gh-26004, the registration order of active profiles in
@ActiveProfiles is preserved; however, the Javadoc in
MergedContextConfiguration and WebMergedContextConfiguration still
described the old sorting behavior, which is misleading since profile
order is part of the context cache key (equals/hashCode).
This commit updates the Javadoc to document the status quo.
Closes gh-36950
Signed-off-by: Alexis SEGURA <alex.segura06@gmail.com>
This commit picks up where ce718cf699 left off by ensuring that
findAllLocalMergedAnnotations() also finds annotations declared on
transitive interfaces — that is, on interfaces of the directly
implemented interfaces of the root declaring class.
The previous implementation filtered annotations from a single
TYPE_HIERARCHY search by checking whether the annotation's source was
either the root declaring class or one of its directly declared
interfaces. However, this excluded annotations inherited through an
interface chain such as First -> Second -> Third, where the annotation
is declared on Third but not on Second.
This commit replaces that approach with two targeted searches whose
results are combined:
- DIRECT on the root declaring class, to capture annotations declared
directly on the class (including via composed/meta-annotations)
- TYPE_HIERARCHY on each directly implemented interface, which
naturally traverses the full super-interface chain of each interface
A corresponding test for this scenario has also been added.
Closes gh-36975
Prior to this commit, AnnotationDescriptor's
findAllLocalMergedAnnotations() filtered results using
MergedAnnotationPredicates.firstRunOf(
MergedAnnotation::getAggregateIndex), which retains only annotations
that share the same aggregate index as the first annotation
encountered. Since annotations on the root declaring class have
aggregate index 0 and annotations on interfaces have higher indices,
interface annotations were silently excluded whenever the root
declaring class itself declared the annotation.
This commit fixes the issue by replacing the aggregate-index-based
filter with a source-based filter that explicitly includes annotations
from the root declaring class and from each directly implemented
interface. The Javadoc for findAllLocalMergedAnnotations() has also
been updated to document the ordering guarantee: annotations from the
root declaring class appear first, followed by annotations from
implemented interfaces in declaration order.
Closes gh-36975
This commit addresses warnings across the code base related to:
- internal and public deprecations in Spring Framework
- deprecated Locale constructors
- deprecated URL constructors
- deprecated Thread#getId method
awaitAsyncDispatch() catches InterruptedException, returns false, and
discards the interruption. Catching InterruptedException without
rethrowing should restore the interrupt status (as is done across the
framework's main sources), so re-assert it before returning false.
Closes gh-36876
Signed-off-by: leestana01 <leestana01@naver.com>
Prior to this commit, MIME type parsing in Spring would allow duplicate
parameters like "text/plain; dupe=1; dupe=2", effectively retaining the
latest value and ignoring the first.
RFC 6838 4.3 states that this should be treated as an error and this
commit ensures that this is the case.
Closes gh-36841
Prior to this commit,
MicrometerObservationRegistryTestExecutionListener always attempted to
load the test's ApplicationContext in order to update the
ObservationThreadLocalAccessor in its beforeTestMethod() callback, even
if there was no active ApplicationContext.
To avoid unnecessarily loading an ApplicationContext or attempting to
load an ApplicationContext that cannot be loaded (for example, due to a
context-load failure), this commit applies a hasApplicationContext()
check in beforeTestMethod().
Since the MicrometerObservationRegistryTestExecutionListener is
registered after the DependencyInjectionTestExecutionListener (at least
by default), an active ApplicationContext should be present unless
dependency injection from the context failed or the context failed to
load.
Closes gh-36817
Prior to this commit and the previous commit,
MockitoResetTestExecutionListener always attempted to load the
ApplicationContext to reset mocks in its beforeTestMethod() and
afterTestMethod() callbacks, even if there was no active
ApplicationContext.
The reason this was noticed is that the @BeforeMethod(alwaysRun = true)
and @AfterMethod(alwaysRun = true) lifecycle methods in
AbstractTestNGSpringContextTests are always invoked, even if a previous
lifecycle configuration method failed (for example, due to a
context-load failure).
However, with JUnit Jupiter and the SpringExtension the
beforeTestMethod() and afterTestMethod() callbacks in the
TestExecutionListener API are not invoked if there was a previous
lifecycle failure.
Consequently, the reported drawbacks only exist when using Spring's
TestNG base support classes
This commit picks up where the previous commit left off by applying the
same hasApplicationContext() check in beforeTestMethod().
This commit also introduces unit and integration tests for both Jupiter
and TestNG support.
Closes gh-36782