Skip to content

Add test support to record async events, with JUnit Jupiter caveat #30020

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Conversation

simonbasle
Copy link
Contributor

This commit modifies the way the @RecordApplicationEvents annotation
works in tests, allowing for capture of events from threads other than
the main test thread (async events) and for the assertion of captured
event from a separate thread (e.g. when using Awaitility).

This is done by switching the ApplicationEventsHolder to use an
InheritedThreadLocal.

There is a mutual exclusion between support of asynchronous events vs
support of JUnit5 parallel tests with the @TestInstance(PER_CLASS)
mode. As a result, we favor the former and now SpringExtension will
invalidate a test class that is annotated (or meta-annotated, or
enclosed-annotated) with @RecordApplicationEvents AND
@TestInstance(PER_CLASS) AND @Execution(CONCURRENT).

Closes gh-29827

@simonbasle simonbasle added this to the 6.1.0-M1 milestone Feb 23, 2023
@simonbasle simonbasle requested a review from sbrannen February 23, 2023 16:42
@simonbasle
Copy link
Contributor Author

cc @odrotbohm

draft as this should probably be slated for 6.1.0

@simonbasle simonbasle force-pushed the 29827-inheritTheadApplicationEvents branch from 085e391 to 05fe8b7 Compare April 25, 2023 14:09
@simonbasle simonbasle marked this pull request as ready for review April 25, 2023 14:10
@simonbasle
Copy link
Contributor Author

Now that main contains work for 6.1.0, this is ready to be reviewed / merged

This commit modifies the way the `@RecordApplicationEvents` annotation
works in tests, allowing for capture of events from threads other than
the main test thread (async events) and for the assertion of captured
event from a separate thread (e.g. when using `Awaitility`).

This is done by switching the `ApplicationEventsHolder` to use an
`InheritedThreadLocal`.

There is a mutual exclusion between support of asynchronous events vs
support of JUnit5 parallel tests with the `@TestInstance(PER_CLASS)`
mode. As a result, we favor the former and now `SpringExtension` will
invalidate a test class that is annotated (or meta-annotated, or
enclosed-annotated) with `@RecordApplicationEvents` AND
`@TestInstance(PER_CLASS)` AND `@Execution(CONCURRENT)`.

See spring-projectsgh-29827
Closes spring-projectsgh-30020
@simonbasle simonbasle force-pushed the 29827-inheritTheadApplicationEvents branch from 3bb0161 to f269a80 Compare May 5, 2023 15:08
@simonbasle simonbasle merged commit b39e93d into spring-projects:main May 5, 2023
@simonbasle simonbasle deleted the 29827-inheritTheadApplicationEvents branch May 5, 2023 15:10
@sbrannen sbrannen removed this from the 6.1.0-M1 milestone May 13, 2023
@sbrannen sbrannen changed the title Add test support to record async events, with Junit5 caveat Add test support to record async events, with JUnit Jupiter caveat May 13, 2023
@sbrannen sbrannen added this to the 6.1.0-M1 milestone May 13, 2023
sbrannen added a commit that referenced this pull request May 13, 2023
Prior to this commit, the SpringExtension looked up the
TestInstance.Lifecycle and ExecutionMode using
TestContextAnnotationUtils; however, using TestContextAnnotationUtils is
problematic since the TestInstance.Lifecycle and ExecutionMode can be
configured globally via configuration parameters instead of locally via
the @testinstance and @execution annotations.

This commit addresses these issues by looking up the
TestInstance.Lifecycle and ExecutionMode via JUnit Jupiter's
ExtensionContext which takes into account both global and local
configuration.

See gh-30020
@sbrannen sbrannen removed their request for review May 13, 2023 17:33
simonbasle added a commit that referenced this pull request Nov 9, 2023
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
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
in: test Issues in the test module type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

@RecordApplicationEvents should record events from spawned threads, too
2 participants