001/* 002 * Copyright 2002-2015 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.support; 018 019import java.lang.reflect.Method; 020 021import org.springframework.context.ApplicationContext; 022import org.springframework.context.ConfigurableApplicationContext; 023import org.springframework.core.AttributeAccessorSupport; 024import org.springframework.core.style.ToStringCreator; 025import org.springframework.test.annotation.DirtiesContext.HierarchyMode; 026import org.springframework.test.context.CacheAwareContextLoaderDelegate; 027import org.springframework.test.context.MergedContextConfiguration; 028import org.springframework.test.context.TestContext; 029import org.springframework.util.Assert; 030 031/** 032 * Default implementation of the {@link TestContext} interface. 033 * 034 * @author Sam Brannen 035 * @author Juergen Hoeller 036 * @since 4.0 037 */ 038public class DefaultTestContext extends AttributeAccessorSupport implements TestContext { 039 040 private static final long serialVersionUID = -5827157174866681233L; 041 042 private final CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate; 043 044 private final MergedContextConfiguration mergedContextConfiguration; 045 046 private final Class<?> testClass; 047 048 private Object testInstance; 049 050 private Method testMethod; 051 052 private Throwable testException; 053 054 055 /** 056 * Construct a new {@code DefaultTestContext} from the supplied arguments. 057 * @param testClass the test class for this test context; never {@code null} 058 * @param mergedContextConfiguration the merged application context 059 * configuration for this test context; never {@code null} 060 * @param cacheAwareContextLoaderDelegate the delegate to use for loading 061 * and closing the application context for this test context; never {@code null} 062 */ 063 public DefaultTestContext(Class<?> testClass, MergedContextConfiguration mergedContextConfiguration, 064 CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate) { 065 Assert.notNull(testClass, "testClass must not be null"); 066 Assert.notNull(mergedContextConfiguration, "MergedContextConfiguration must not be null"); 067 Assert.notNull(cacheAwareContextLoaderDelegate, "CacheAwareContextLoaderDelegate must not be null"); 068 this.testClass = testClass; 069 this.mergedContextConfiguration = mergedContextConfiguration; 070 this.cacheAwareContextLoaderDelegate = cacheAwareContextLoaderDelegate; 071 } 072 073 /** 074 * Get the {@linkplain ApplicationContext application context} for this 075 * test context. 076 * <p>The default implementation delegates to the {@link CacheAwareContextLoaderDelegate} 077 * that was supplied when this {@code TestContext} was constructed. 078 * @see CacheAwareContextLoaderDelegate#loadContext 079 * @throws IllegalStateException if the context returned by the context 080 * loader delegate is not <em>active</em> (i.e., has been closed). 081 */ 082 public ApplicationContext getApplicationContext() { 083 ApplicationContext context = this.cacheAwareContextLoaderDelegate.loadContext(this.mergedContextConfiguration); 084 if (context instanceof ConfigurableApplicationContext) { 085 @SuppressWarnings("resource") 086 ConfigurableApplicationContext cac = (ConfigurableApplicationContext) context; 087 Assert.state(cac.isActive(), "The ApplicationContext loaded for [" + mergedContextConfiguration 088 + "] is not active. Ensure that the context has not been closed programmatically."); 089 } 090 return context; 091 } 092 093 /** 094 * Mark the {@linkplain ApplicationContext application context} associated 095 * with this test context as <em>dirty</em> (i.e., by removing it from the 096 * context cache and closing it). 097 * <p>The default implementation delegates to the {@link CacheAwareContextLoaderDelegate} 098 * that was supplied when this {@code TestContext} was constructed. 099 * @see CacheAwareContextLoaderDelegate#closeContext 100 */ 101 public void markApplicationContextDirty(HierarchyMode hierarchyMode) { 102 this.cacheAwareContextLoaderDelegate.closeContext(this.mergedContextConfiguration, hierarchyMode); 103 } 104 105 public final Class<?> getTestClass() { 106 return this.testClass; 107 } 108 109 public final Object getTestInstance() { 110 return this.testInstance; 111 } 112 113 public final Method getTestMethod() { 114 return this.testMethod; 115 } 116 117 public final Throwable getTestException() { 118 return this.testException; 119 } 120 121 public void updateState(Object testInstance, Method testMethod, Throwable testException) { 122 this.testInstance = testInstance; 123 this.testMethod = testMethod; 124 this.testException = testException; 125 } 126 127 128 /** 129 * Provide a String representation of this test context's state. 130 */ 131 @Override 132 public String toString() { 133 return new ToStringCreator(this) 134 .append("testClass", this.testClass) 135 .append("testInstance", this.testInstance) 136 .append("testMethod", this.testMethod) 137 .append("testException", this.testException) 138 .append("mergedContextConfiguration", this.mergedContextConfiguration) 139 .toString(); 140 } 141 142}