Go to file
Sam Brannen 1565f4b83e Introduce ApplicationEvents to assert events published during tests
This commit introduces a new feature in the Spring TestContext
Framework (TCF) that provides support for recording application events
published in the ApplicationContext so that assertions can be performed
against those events within tests. All events published during the
execution of a single test are made available via the ApplicationEvents
API which allows one to process the events as a java.util.Stream.

The following example demonstrates usage of this new feature.

@SpringJUnitConfig(/* ... */)
@RecordApplicationEvents
class OrderServiceTests {

    @Autowired
    OrderService orderService;

    @Autowired
    ApplicationEvents events;

    @Test
    void submitOrder() {
        // Invoke method in OrderService that publishes an event
        orderService.submitOrder(new Order(/* ... */));
        // Verify that an OrderSubmitted event was published
        int numEvents = events.stream(OrderSubmitted.class).count();
        assertThat(numEvents).isEqualTo(1);
    }
}

To enable the feature, a test class must be annotated or meta-annotated
with @RecordApplicationEvents. Behind the scenes, a new
ApplicationEventsTestExecutionListener manages the registration of
ApplicationEvents for the current thread at various points within the
test execution lifecycle and makes the current instance of
ApplicationEvents available to tests via an @Autowired field in the
test class. The latter is made possible by a custom ObjectFactory that
is registered as a "resolvable dependency". Thanks to the magic of
ObjectFactoryDelegatingInvocationHandler in the spring-beans module,
the ApplicationEvents instance injected into test classes is
effectively a scoped-proxy that always accesses the ApplicationEvents
managed for the current test.

The current ApplicationEvents instance is stored in a ThreadLocal
variable which is made available in the ApplicationEventsHolder.
Although this class is public, it is only intended for use within the
TCF or in the implementation of third-party extensions.

ApplicationEventsApplicationListener is responsible for listening to
all application events and recording them in the current
ApplicationEvents instance. A single
ApplicationEventsApplicationListener is registered with the test's
ApplicationContext by the ApplicationEventsTestExecutionListener.

The SpringExtension has also been updated to support parameters of type
ApplicationEvents via the JUnit Jupiter ParameterResolver extension
API. This allows JUnit Jupiter based tests to receive access to the
current ApplicationEvents via test and lifecycle method parameters as
an alternative to @Autowired fields in the test class.

Closes gh-25616
2020-12-20 23:46:19 +01:00
.github Configure Gradle wrapper validation action 2020-06-02 14:43:45 +02:00
buildSrc Upgrade to Gradle Enterprise 3.2 2020-04-29 10:54:03 +02:00
ci Remove JDK14 CI variant from build pipeline 2020-12-11 11:08:33 +01:00
framework-bom Remove BOM workaround 2020-04-28 15:14:02 +02:00
gradle Upgrade reference docs dependencies 2020-12-08 11:38:39 +01:00
integration-tests Drop explicit zeroing at instantiation of Atomic* objects 2020-10-06 15:45:12 +02:00
spring-aop Always propagate checked exceptions from Kotlin code behind CGLIB proxies 2020-12-18 11:55:20 +01:00
spring-aspects Polishing 2020-11-16 17:42:22 +01:00
spring-beans Consistent handling of NullBean instances in resolveNamedBean 2020-12-16 22:27:41 +01:00
spring-context Consistent handling of NullBean instances in resolveNamedBean 2020-12-16 22:27:41 +01:00
spring-context-indexer Polish contribution 2020-07-22 14:06:29 +02:00
spring-context-support Requalify tests as LONG_RUNNING 2020-09-25 13:43:38 +02:00
spring-core Introduce computeAttribute() in AttributeAccessor 2020-12-15 22:47:02 +01:00
spring-expression Polishing 2020-12-08 14:59:10 +01:00
spring-instrument Delete obsolete log4j config 2020-03-18 17:01:01 +01:00
spring-jcl Polishing 2020-01-28 21:56:35 +01:00
spring-jdbc Translate PostgreSQL code 21000 (cardinality_violation) 2020-12-16 22:27:57 +01:00
spring-jms Compatibility with Jackson 2.12 (tested against 2.12.0-rc1) 2020-10-13 11:04:55 +02:00
spring-messaging Avoid CGLIB proxies on websocket/messaging configurations 2020-12-07 12:18:29 +01:00
spring-orm Early log entry for async EntityManagerFactory initialization failure 2020-11-13 17:52:51 +01:00
spring-oxm Merge branch '5.2.x' 2020-08-30 12:18:49 +02:00
spring-r2dbc Improve URI/query strings sanitization 2020-11-04 16:28:51 +01:00
spring-test Introduce ApplicationEvents to assert events published during tests 2020-12-20 23:46:19 +01:00
spring-tx Document that @Transactional does not propagate to new threads 2020-11-17 14:43:17 +01:00
spring-web Update async dispatch check in OncePerRequestFilter 2020-12-17 17:33:39 +00:00
spring-webflux Clean up warnings in Gradle build 2020-12-15 22:47:02 +01:00
spring-webmvc Clear path pattern in HandlerMapping 2020-12-08 13:06:45 +01:00
spring-websocket Polishing 2020-12-08 10:39:56 +01:00
src Introduce ApplicationEvents to assert events published during tests 2020-12-20 23:46:19 +01:00
.editorconfig Add EditorConfig 2017-06-12 08:07:54 +02:00
.gitattributes Ensure line endings for binary files are not modified in Git 2019-10-18 11:56:18 +02:00
.gitignore Rename non-Framework project modules 2019-08-21 14:32:25 +02:00
.mailmap Change gopivotal.com to pivotal.io 2014-10-05 18:12:50 +02:00
CODE_OF_CONDUCT.adoc URL Cleanup 2019-03-21 15:08:55 -05:00
CONTRIBUTING.md Update StackOverflow link 2020-04-20 12:32:11 +01:00
LICENSE.txt Add LICENSE.txt file 2019-08-20 22:01:12 +02:00
README.md Add JMH benchmark infrastructure 2020-05-13 21:29:02 +02:00
SECURITY.md Create SECURITY.md 2019-05-23 11:36:52 -04:00
build.gradle Upgrade to Hibernate Validator 6.1.7, Jetty Reactive HttpClient 1.1.5, Joda-Time 2.10.8, XMLUnit 2.8.1 2020-12-17 10:46:13 +01:00
gradle.properties Next development version (v5.3.3-SNAPSHOT) 2020-12-09 06:11:23 +00:00
gradlew Upgrade to Gradle 6.6 2020-08-11 12:10:35 +02:00
gradlew.bat Upgrade to Gradle 6.6 2020-08-11 12:10:35 +02:00
import-into-eclipse.md Polishing regarding AJDT versions 2020-01-13 17:15:27 +01:00
import-into-idea.md URL Cleanup 2019-03-21 15:08:55 -05:00
settings.gradle Include module names into alphabetical order 2020-06-24 16:08:21 +02:00

README.md

Spring Framework Build Status

This is the home of the Spring Framework: the foundation for all Spring projects. Collectively the Spring Framework and the family of Spring projects are often referred to simply as "Spring".

Spring provides everything required beyond the Java programming language for creating enterprise applications for a wide range of scenarios and architectures. Please read the Overview section as reference for a more complete introduction.

Code of Conduct

This project is governed by the Spring Code of Conduct. By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.

Access to Binaries

For access to artifacts or a distribution zip, see the Spring Framework Artifacts wiki page.

Documentation

The Spring Framework maintains reference documentation (published and source), Github wiki pages, and an API reference. There are also guides and tutorials across Spring projects.

Micro-Benchmarks

See the Micro-Benchmarks Wiki page.

Build from Source

See the Build from Source Wiki page and the CONTRIBUTING.md file.

Stay in Touch

Follow @SpringCentral, @SpringFramework, and its team members on Twitter. In-depth articles can be found at The Spring Blog, and releases are announced via our news feed.

License

The Spring Framework is released under version 2.0 of the Apache License.