001/*
002 * Copyright 2002-2019 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.test.context.event;
018
019import org.springframework.test.context.TestContext;
020import org.springframework.test.context.TestExecutionListener;
021import org.springframework.test.context.support.AbstractTestExecutionListener;
022
023/**
024 * {@link org.springframework.test.context.TestExecutionListener TestExecutionListener}
025 * that publishes test execution events to the
026 * {@link org.springframework.context.ApplicationContext ApplicationContext}
027 * for the currently executing test. Events are only published if the
028 * {@code ApplicationContext} {@linkplain TestContext#hasApplicationContext()
029 * has already been loaded}.
030 *
031 * <h3>Supported Events</h3>
032 * <ul>
033 * <li>{@link BeforeTestClassEvent}</li>
034 * <li>{@link PrepareTestInstanceEvent}</li>
035 * <li>{@link BeforeTestMethodEvent}</li>
036 * <li>{@link BeforeTestExecutionEvent}</li>
037 * <li>{@link AfterTestExecutionEvent}</li>
038 * <li>{@link AfterTestMethodEvent}</li>
039 * <li>{@link AfterTestClassEvent}</li>
040 * </ul>
041 *
042 * <p>These events may be consumed for various reasons, such as resetting <em>mock</em>
043 * beans or tracing test execution. One advantage of consuming test events rather
044 * than implementing a custom {@link TestExecutionListener} is that test events
045 * may be consumed by any Spring bean registered in the test {@code ApplicationContext},
046 * and such beans may benefit directly from dependency injection and other features
047 * of the {@code ApplicationContext}. In contrast, a {@link TestExecutionListener}
048 * is not a bean in the {@code ApplicationContext}.
049 *
050 * <h3>Exception Handling</h3>
051 * <p>By default, if a test event listener throws an exception while consuming
052 * a test event, that exception will propagate to the underlying testing framework
053 * in use. For example, if the consumption of a {@code BeforeTestMethodEvent}
054 * results in an exception, the corresponding test method will fail as a result
055 * of the exception. In contrast, if an asynchronous test event listener throws
056 * an exception, the exception will not propagate to the underlying testing framework.
057 * For further details on asynchronous exception handling, consult the class-level
058 * Javadoc for {@link org.springframework.context.event.EventListener @EventListener}.
059 *
060 * <h3>Asynchronous Listeners</h3>
061 * <p>If you want a particular test event listener to process events asynchronously,
062 * you can use Spring's {@link org.springframework.scheduling.annotation.Async @Async}
063 * support. For further details, consult the class-level Javadoc for
064 * {@link org.springframework.context.event.EventListener @EventListener}.
065 *
066 * @author Sam Brannen
067 * @author Frank Scheffler
068 * @since 5.2
069 * @see org.springframework.test.context.event.annotation.BeforeTestClass @BeforeTestClass
070 * @see org.springframework.test.context.event.annotation.PrepareTestInstance @PrepareTestInstance
071 * @see org.springframework.test.context.event.annotation.BeforeTestMethod @BeforeTestMethod
072 * @see org.springframework.test.context.event.annotation.BeforeTestExecution @BeforeTestExecution
073 * @see org.springframework.test.context.event.annotation.AfterTestExecution @AfterTestExecution
074 * @see org.springframework.test.context.event.annotation.AfterTestMethod @AfterTestMethod
075 * @see org.springframework.test.context.event.annotation.AfterTestClass @AfterTestClass
076 */
077public class EventPublishingTestExecutionListener extends AbstractTestExecutionListener {
078
079        /**
080         * Returns {@code 10000}.
081         */
082        @Override
083        public final int getOrder() {
084                return 10_000;
085        }
086
087        /**
088         * Publish a {@link BeforeTestClassEvent} to the {@code ApplicationContext}
089         * for the supplied {@link TestContext}.
090         */
091        @Override
092        public void beforeTestClass(TestContext testContext) {
093                testContext.publishEvent(BeforeTestClassEvent::new);
094        }
095
096        /**
097         * Publish a {@link PrepareTestInstanceEvent} to the {@code ApplicationContext}
098         * for the supplied {@link TestContext}.
099         */
100        @Override
101        public void prepareTestInstance(TestContext testContext) {
102                testContext.publishEvent(PrepareTestInstanceEvent::new);
103        }
104
105        /**
106         * Publish a {@link BeforeTestMethodEvent} to the {@code ApplicationContext}
107         * for the supplied {@link TestContext}.
108         */
109        @Override
110        public void beforeTestMethod(TestContext testContext) {
111                testContext.publishEvent(BeforeTestMethodEvent::new);
112        }
113
114        /**
115         * Publish a {@link BeforeTestExecutionEvent} to the {@code ApplicationContext}
116         * for the supplied {@link TestContext}.
117         */
118        @Override
119        public void beforeTestExecution(TestContext testContext) {
120                testContext.publishEvent(BeforeTestExecutionEvent::new);
121        }
122
123        /**
124         * Publish an {@link AfterTestExecutionEvent} to the {@code ApplicationContext}
125         * for the supplied {@link TestContext}.
126         */
127        @Override
128        public void afterTestExecution(TestContext testContext) {
129                testContext.publishEvent(AfterTestExecutionEvent::new);
130        }
131
132        /**
133         * Publish an {@link AfterTestMethodEvent} to the {@code ApplicationContext}
134         * for the supplied {@link TestContext}.
135         */
136        @Override
137        public void afterTestMethod(TestContext testContext) {
138                testContext.publishEvent(AfterTestMethodEvent::new);
139        }
140
141        /**
142         * Publish an {@link AfterTestClassEvent} to the {@code ApplicationContext}
143         * for the supplied {@link TestContext}.
144         */
145        @Override
146        public void afterTestClass(TestContext testContext) {
147                testContext.publishEvent(AfterTestClassEvent::new);
148        }
149
150}