/** * Copyright (C) 2008 Mathieu Carbou <mathieu.carbou@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mycila.testing.plugin.spring; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import org.springframework.util.ClassUtils; import com.mycila.testing.core.api.TestContext; import com.mycila.testing.core.api.TestExecution; import com.mycila.testing.core.plugin.DefaultTestPlugin; /** * @author Mathieu Carbou (mathieu.carbou@gmail.com) */ public final class SpringTestPlugin extends DefaultTestPlugin { public static final String TESTCONTEXTMANAGER = "org.springframework.test.context.TestContextManager"; public static final String TESTCONTEXT = "org.springframework.test.context.TestContext"; public static final String APPLICATIONCONTEXT = "org.springframework.context.ApplicationContext"; @Override public void prepareTestInstance(TestContext context) { try { final TestContextManager manager = new TestContextManager(context.introspector().testClass()); final org.springframework.test.context.TestContext ctx = manager.testContext(); context.attributes().set(TESTCONTEXTMANAGER, manager); if ( isSpring31() ) { //Changed in http://www.swiftmind.com/de/2011/06/22/spring-3-1-m2-testing-with-configuration-classes-and-profiles/ "ApplicationContext Caching" - so force a refresh here ctx.markApplicationContextDirty(); } context.attributes().set(TESTCONTEXT, ctx); setupContextLoader(ctx, new MycilaContextLoader(context)); context.attributes().set(APPLICATIONCONTEXT, manager.testContext().getApplicationContext()); manager.prepareTestInstance(context.introspector().instance()); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } @Override public void afterTest(TestExecution testExecution) throws Exception { TestContextManager manager = testExecution.context().attributes().get(TESTCONTEXTMANAGER); manager.afterTestMethod( testExecution.context().introspector().instance(), testExecution.method(), testExecution.throwable()); } @Override public void beforeTest(TestExecution testExecution) throws Exception { TestContextManager manager = testExecution.context().attributes().get(TESTCONTEXTMANAGER); manager.beforeTestMethod( testExecution.context().introspector().instance(), testExecution.method()); } private boolean isSpring31() { return ClassUtils.isPresent( "org.springframework.test.context.MergedContextConfiguration", getClass().getClassLoader() ); } private void setupContextLoader(org.springframework.test.context.TestContext ctx, MycilaContextLoader loader) throws Exception { if ( !isSpring31() ) { Field locations = ctx.getClass().getDeclaredField("locations"); locations.setAccessible(true); locations.set(ctx, loader.contextLocations()); Field contextLoader = ctx.getClass().getDeclaredField("contextLoader"); contextLoader.setAccessible(true); contextLoader.set(ctx, loader); Field contextCache = ctx.getClass().getDeclaredField("contextCache"); contextCache.setAccessible(true); Constructor<?> ctor = Class.forName("org.springframework.test.context.ContextCache").getDeclaredConstructor(); ctor.setAccessible(true); contextCache.set(ctx, ctor.newInstance()); } else { Field mergedContextConfigurationField = ctx.getClass().getDeclaredField("mergedContextConfiguration"); mergedContextConfigurationField.setAccessible(true); Object mergedContextConfiguration = mergedContextConfigurationField.get(ctx); Field locations = mergedContextConfiguration.getClass().getDeclaredField("locations"); locations.setAccessible(true); locations.set(mergedContextConfiguration, loader.contextLocations()); Field contextLoaderField = mergedContextConfiguration.getClass().getDeclaredField("contextLoader"); contextLoaderField.setAccessible(true); contextLoaderField.set(mergedContextConfiguration, loader); } } private static class TestContextManager extends org.springframework.test.context.TestContextManager { public TestContextManager(Class<?> testClass) { super(testClass); } public org.springframework.test.context.TestContext testContext() { return super.getTestContext(); } } }