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; 018 019import java.io.Serializable; 020import java.lang.reflect.Method; 021import java.util.function.Function; 022 023import org.springframework.context.ApplicationContext; 024import org.springframework.context.ApplicationEvent; 025import org.springframework.core.AttributeAccessor; 026import org.springframework.lang.Nullable; 027import org.springframework.test.annotation.DirtiesContext.HierarchyMode; 028 029/** 030 * {@code TestContext} encapsulates the context in which a test is executed, 031 * agnostic of the actual testing framework in use. 032 * 033 * <p>As of Spring Framework 5.0, concrete implementations are highly encouraged 034 * to implement a <em>copy constructor</em> in order to allow the immutable state 035 * and attributes of a {@code TestContext} to be used as a template for additional 036 * contexts created for parallel test execution. The copy constructor must accept a 037 * single argument of the type of the concrete implementation. Any implementation 038 * that does not provide a copy constructor will likely fail in an environment 039 * that executes tests concurrently. 040 * 041 * @author Sam Brannen 042 * @since 2.5 043 * @see TestContextManager 044 * @see TestExecutionListener 045 */ 046// Suppression required due to bug in javac in Java 8: presence of default method in a Serializable interface 047@SuppressWarnings("serial") 048public interface TestContext extends AttributeAccessor, Serializable { 049 050 /** 051 * Determine if the {@linkplain ApplicationContext application context} for 052 * this test context is known to be available. 053 * <p>If this method returns {@code true}, a subsequent invocation of 054 * {@link #getApplicationContext()} should succeed. 055 * <p>The default implementation of this method always returns {@code false}. 056 * Custom {@code TestContext} implementations are therefore highly encouraged 057 * to override this method with a more meaningful implementation. Note that 058 * the standard {@code TestContext} implementation in Spring overrides this 059 * method appropriately. 060 * @return {@code true} if the application context has already been loaded 061 * @since 5.2 062 * @see #getApplicationContext() 063 */ 064 default boolean hasApplicationContext() { 065 return false; 066 } 067 068 /** 069 * Get the {@linkplain ApplicationContext application context} for this 070 * test context, possibly cached. 071 * <p>Implementations of this method are responsible for loading the 072 * application context if the corresponding context has not already been 073 * loaded, potentially caching the context as well. 074 * @return the application context (never {@code null}) 075 * @throws IllegalStateException if an error occurs while retrieving the 076 * application context 077 * @see #hasApplicationContext() 078 */ 079 ApplicationContext getApplicationContext(); 080 081 /** 082 * Publish the {@link ApplicationEvent} created by the given {@code eventFactory} 083 * to the {@linkplain ApplicationContext application context} for this 084 * test context. 085 * <p>The {@code ApplicationEvent} will only be published if the application 086 * context for this test context {@linkplain #hasApplicationContext() is available}. 087 * @param eventFactory factory for lazy creation of the {@code ApplicationEvent} 088 * @since 5.2 089 * @see #hasApplicationContext() 090 * @see #getApplicationContext() 091 */ 092 default void publishEvent(Function<TestContext, ? extends ApplicationEvent> eventFactory) { 093 if (hasApplicationContext()) { 094 getApplicationContext().publishEvent(eventFactory.apply(this)); 095 } 096 } 097 098 /** 099 * Get the {@linkplain Class test class} for this test context. 100 * @return the test class (never {@code null}) 101 */ 102 Class<?> getTestClass(); 103 104 /** 105 * Get the current {@linkplain Object test instance} for this test context. 106 * <p>Note: this is a mutable property. 107 * @return the current test instance (never {@code null}) 108 * @see #updateState(Object, Method, Throwable) 109 */ 110 Object getTestInstance(); 111 112 /** 113 * Get the current {@linkplain Method test method} for this test context. 114 * <p>Note: this is a mutable property. 115 * @return the current test method (never {@code null}) 116 * @see #updateState(Object, Method, Throwable) 117 */ 118 Method getTestMethod(); 119 120 /** 121 * Get the {@linkplain Throwable exception} that was thrown during execution 122 * of the {@linkplain #getTestMethod() test method}. 123 * <p>Note: this is a mutable property. 124 * @return the exception that was thrown, or {@code null} if no exception was thrown 125 * @see #updateState(Object, Method, Throwable) 126 */ 127 @Nullable 128 Throwable getTestException(); 129 130 /** 131 * Call this method to signal that the {@linkplain ApplicationContext application 132 * context} associated with this test context is <em>dirty</em> and should be 133 * removed from the context cache. 134 * <p>Do this if a test has modified the context — for example, by 135 * modifying the state of a singleton bean, modifying the state of an embedded 136 * database, etc. 137 * @param hierarchyMode the context cache clearing mode to be applied if the 138 * context is part of a hierarchy (may be {@code null}) 139 */ 140 void markApplicationContextDirty(@Nullable HierarchyMode hierarchyMode); 141 142 /** 143 * Update this test context to reflect the state of the currently executing test. 144 * <p><strong>WARNING</strong>: This method should only be invoked by the 145 * {@link TestContextManager}. 146 * <p>Caution: concurrent invocations of this method might not be thread-safe, 147 * depending on the underlying implementation. 148 * @param testInstance the current test instance (may be {@code null}) 149 * @param testMethod the current test method (may be {@code null}) 150 * @param testException the exception that was thrown in the test method, 151 * or {@code null} if no exception was thrown 152 */ 153 void updateState(@Nullable Object testInstance, @Nullable Method testMethod, @Nullable Throwable testException); 154 155}