Introduce ActiveProfilesResolver in the TCF
Prior to this commit, the active bean definition profiles to use when loading an ApplicationContext for tests could only be configured declaratively (i.e., via hard-coded values supplied to the 'value' or 'profiles' attribute of @ActiveProfiles). This commit makes it possible to programmatically configure active bean definition profiles in tests via a new ActiveProfileResolver interface. Custom resolvers can be registered via a new 'resolver' attribute introduced in @ActiveProfiles. Overview of changes: - Introduced a new ActiveProfilesResolver API. - Added a 'resolver' attribute to @ActiveProfiles. - Updated ContextLoaderUtils.resolveActiveProfiles() to support ActiveProfilesResolvers. - Documented these new features in the reference manual. - Added new content to the reference manual regarding the 'inheritProfiles' attribute of @ActiveProfiles - Removed the use of <lineannotation> Docbook markup in the testing chapter of the reference manual for Java code examples in order to allow comments to have proper syntax highlighting in the generated HTML and PDF. Issue: SPR-10338
This commit is contained in:
@@ -32,6 +32,7 @@ import static org.springframework.test.context.SpringRunnerContextCacheTests.*;
|
||||
* conjunction with cache keys used in {@link TestContext}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @author Michail Nikolaev
|
||||
* @since 3.1
|
||||
* @see SpringRunnerContextCacheTests
|
||||
*/
|
||||
@@ -84,6 +85,7 @@ public class ContextCacheTests {
|
||||
loadCtxAndAssertStats(FooBarProfilesTestCase.class, 1, 3, 1);
|
||||
loadCtxAndAssertStats(FooBarProfilesTestCase.class, 1, 4, 1);
|
||||
loadCtxAndAssertStats(BarFooProfilesTestCase.class, 1, 5, 1);
|
||||
loadCtxAndAssertStats(FooBarActiveProfilesResolverTestCase.class, 1, 6, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -287,6 +289,19 @@ public class ContextCacheTests {
|
||||
private static class BarFooProfilesTestCase {
|
||||
}
|
||||
|
||||
private static class FooBarActiveProfilesResolver implements ActiveProfilesResolver {
|
||||
|
||||
@Override
|
||||
public String[] resolve(Class<?> testClass) {
|
||||
return new String[] { "foo", "bar" };
|
||||
}
|
||||
}
|
||||
|
||||
@ActiveProfiles(resolver = FooBarActiveProfilesResolver.class)
|
||||
@ContextConfiguration(classes = Config.class, loader = AnnotationConfigContextLoader.class)
|
||||
private static class FooBarActiveProfilesResolverTestCase {
|
||||
}
|
||||
|
||||
@ContextHierarchy({ @ContextConfiguration })
|
||||
private static class ClassHierarchyContextHierarchyLevel1TestCase {
|
||||
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
|
||||
package org.springframework.test.context;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.test.context.ContextLoaderUtils.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@@ -38,10 +34,15 @@ import org.springframework.test.context.support.DelegatingSmartContextLoader;
|
||||
import org.springframework.test.context.support.GenericPropertiesContextLoader;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.test.context.ContextLoaderUtils.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ContextLoaderUtils}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @author Michail Nikolaev
|
||||
* @since 3.1
|
||||
*/
|
||||
public class ContextLoaderUtilsTests {
|
||||
@@ -606,8 +607,94 @@ public class ContextLoaderUtilsTests {
|
||||
assertTrue(list.contains("cat"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
@Test
|
||||
public void resolveActiveProfilesWithResolver() {
|
||||
String[] profiles = resolveActiveProfiles(FooActiveProfilesResolverTest.class);
|
||||
assertNotNull(profiles);
|
||||
assertEquals(1, profiles.length);
|
||||
assertArrayEquals(new String[] { "foo" }, profiles);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
@Test
|
||||
public void resolveActiveProfilesWithInheritedResolver() {
|
||||
String[] profiles = resolveActiveProfiles(InheritedFooActiveProfilesResolverTest.class);
|
||||
assertNotNull(profiles);
|
||||
assertEquals(1, profiles.length);
|
||||
assertArrayEquals(new String[] { "foo" }, profiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
@Test
|
||||
public void resolveActiveProfilesWithMergedInheritedResolver() {
|
||||
String[] profiles = resolveActiveProfiles(MergedInheritedFooActiveProfilesResolverTest.class);
|
||||
assertNotNull(profiles);
|
||||
assertEquals(2, profiles.length);
|
||||
List<String> list = Arrays.asList(profiles);
|
||||
assertTrue(list.contains("foo"));
|
||||
assertTrue(list.contains("bar"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
@Test
|
||||
public void resolveActiveProfilesWithOverridenInheritedResolver() {
|
||||
String[] profiles = resolveActiveProfiles(OverridenInheritedFooActiveProfilesResolverTest.class);
|
||||
assertNotNull(profiles);
|
||||
assertEquals(1, profiles.length);
|
||||
assertArrayEquals(new String[] { "bar" }, profiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void resolveActiveProfilesWithConflictingResolverAndProfiles() {
|
||||
resolveActiveProfiles(ConflictingResolverAndProfilesTest.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void resolveActiveProfilesWithConflictingResolverAndValue() {
|
||||
resolveActiveProfiles(ConflictingResolverAndValueTest.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void resolveActiveProfilesWithConflictingProfilesAndValue() {
|
||||
resolveActiveProfiles(ConflictingProfilesAndValueTest.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void resolveActiveProfilesWithResolverWithoutDefaultConstructor() {
|
||||
resolveActiveProfiles(NoDefaultConstructorActiveProfilesResolverTest.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void resolveActiveProfilesWithResolverThatReturnsNull() {
|
||||
resolveActiveProfiles(NullActiveProfilesResolverTest.class);
|
||||
}
|
||||
|
||||
|
||||
// --- General Purpose Classes and Config ----------------------------------
|
||||
|
||||
private static class Enigma {
|
||||
}
|
||||
@@ -677,6 +764,80 @@ public class ContextLoaderUtilsTests {
|
||||
private static class Animals extends LocationsBar {
|
||||
}
|
||||
|
||||
// --- ActiveProfilesResolver ----------------------------------------------
|
||||
|
||||
public static class FooActiveProfilesResolver implements ActiveProfilesResolver {
|
||||
|
||||
@Override
|
||||
public String[] resolve(Class<?> testClass) {
|
||||
return new String[] { "foo" };
|
||||
}
|
||||
}
|
||||
|
||||
public static class BarActiveProfilesResolver implements ActiveProfilesResolver {
|
||||
|
||||
@Override
|
||||
public String[] resolve(Class<?> testClass) {
|
||||
return new String[] { "bar" };
|
||||
}
|
||||
}
|
||||
|
||||
public static class NullActiveProfilesResolver implements ActiveProfilesResolver {
|
||||
|
||||
@Override
|
||||
public String[] resolve(Class<?> testClass) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class NoDefaultConstructorActiveProfilesResolver implements ActiveProfilesResolver {
|
||||
|
||||
public NoDefaultConstructorActiveProfilesResolver(Object agument) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] resolve(Class<?> testClass) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ActiveProfiles(resolver = NullActiveProfilesResolver.class)
|
||||
private static class NullActiveProfilesResolverTest {
|
||||
}
|
||||
|
||||
@ActiveProfiles(resolver = NoDefaultConstructorActiveProfilesResolver.class)
|
||||
private static class NoDefaultConstructorActiveProfilesResolverTest {
|
||||
}
|
||||
|
||||
@ActiveProfiles(resolver = FooActiveProfilesResolver.class)
|
||||
private static class FooActiveProfilesResolverTest {
|
||||
}
|
||||
|
||||
private static class InheritedFooActiveProfilesResolverTest extends FooActiveProfilesResolverTest {
|
||||
}
|
||||
|
||||
@ActiveProfiles(resolver = BarActiveProfilesResolver.class)
|
||||
private static class MergedInheritedFooActiveProfilesResolverTest extends InheritedFooActiveProfilesResolverTest {
|
||||
}
|
||||
|
||||
@ActiveProfiles(resolver = BarActiveProfilesResolver.class, inheritProfiles = false)
|
||||
private static class OverridenInheritedFooActiveProfilesResolverTest extends InheritedFooActiveProfilesResolverTest {
|
||||
}
|
||||
|
||||
@ActiveProfiles(resolver = BarActiveProfilesResolver.class, profiles = "conflict")
|
||||
private static class ConflictingResolverAndProfilesTest {
|
||||
}
|
||||
|
||||
@ActiveProfiles(resolver = BarActiveProfilesResolver.class, value = "conflict")
|
||||
private static class ConflictingResolverAndValueTest {
|
||||
}
|
||||
|
||||
@ActiveProfiles(profiles = "conflict", value = "conflict")
|
||||
private static class ConflictingProfilesAndValueTest {
|
||||
}
|
||||
|
||||
// --- ApplicationContextInitializer ---------------------------------------
|
||||
|
||||
private static class FooInitializer implements ApplicationContextInitializer<GenericApplicationContext> {
|
||||
|
||||
@Override
|
||||
@@ -707,6 +868,8 @@ public class ContextLoaderUtilsTests {
|
||||
private static class OverriddenInitializersAndClassesBar extends InitializersFoo {
|
||||
}
|
||||
|
||||
// --- @ContextHierarchy ---------------------------------------------------
|
||||
|
||||
@ContextConfiguration("foo.xml")
|
||||
@ContextHierarchy(@ContextConfiguration("bar.xml"))
|
||||
private static class SingleTestClassWithContextConfigurationAndContextHierarchy {
|
||||
|
||||
@@ -37,7 +37,9 @@ import org.springframework.test.context.junit4.annotation.ExplicitConfigClassesI
|
||||
import org.springframework.test.context.junit4.orm.HibernateSessionFlushingTests;
|
||||
import org.springframework.test.context.junit4.profile.annotation.DefaultProfileAnnotationConfigTests;
|
||||
import org.springframework.test.context.junit4.profile.annotation.DevProfileAnnotationConfigTests;
|
||||
import org.springframework.test.context.junit4.profile.annotation.DevProfileResolverAnnotationConfigTests;
|
||||
import org.springframework.test.context.junit4.profile.xml.DefaultProfileXmlConfigTests;
|
||||
import org.springframework.test.context.junit4.profile.xml.DevProfileResolverXmlConfigTests;
|
||||
import org.springframework.test.context.junit4.profile.xml.DevProfileXmlConfigTests;
|
||||
|
||||
/**
|
||||
@@ -77,8 +79,10 @@ StandardJUnit4FeaturesTests.class,//
|
||||
DefaultLoaderBeanOverridingExplicitConfigClassesInheritedTests.class,//
|
||||
DefaultProfileAnnotationConfigTests.class,//
|
||||
DevProfileAnnotationConfigTests.class,//
|
||||
DevProfileResolverAnnotationConfigTests.class,//
|
||||
DefaultProfileXmlConfigTests.class,//
|
||||
DevProfileXmlConfigTests.class,//
|
||||
DevProfileResolverXmlConfigTests.class,//
|
||||
ExpectedExceptionSpringRunnerTests.class,//
|
||||
TimedSpringRunnerTests.class,//
|
||||
RepeatedSpringRunnerTests.class,//
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.test.context.junit4.profile.annotation;
|
||||
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.ActiveProfilesResolver;
|
||||
|
||||
/**
|
||||
* @author Michail Nikolaev
|
||||
* @since 4.0
|
||||
*/
|
||||
@ActiveProfiles(resolver = DevProfileResolverAnnotationConfigTests.class, inheritProfiles = false)
|
||||
public class DevProfileResolverAnnotationConfigTests extends DevProfileAnnotationConfigTests implements
|
||||
ActiveProfilesResolver {
|
||||
|
||||
@Override
|
||||
public String[] resolve(Class<?> testClass) {
|
||||
return new String[] { "dev" };
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,7 +31,8 @@ import org.junit.runners.Suite.SuiteClasses;
|
||||
// Note: the following 'multi-line' layout is for enhanced code readability.
|
||||
@SuiteClasses({//
|
||||
DefaultProfileAnnotationConfigTests.class,//
|
||||
DevProfileAnnotationConfigTests.class //
|
||||
DevProfileAnnotationConfigTests.class,//
|
||||
DevProfileResolverAnnotationConfigTests.class //
|
||||
})
|
||||
public class ProfileAnnotationConfigTestSuite {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.test.context.junit4.profile.importresource;
|
||||
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.ActiveProfilesResolver;
|
||||
|
||||
/**
|
||||
* @author Michail Nikolaev
|
||||
* @since 4.0
|
||||
*/
|
||||
@ActiveProfiles(resolver = DevProfileResolverAnnotationConfigTests.class, inheritProfiles = false)
|
||||
public class DevProfileResolverAnnotationConfigTests extends DevProfileAnnotationConfigTests implements
|
||||
ActiveProfilesResolver {
|
||||
|
||||
@Override
|
||||
public String[] resolve(Class<?> testClass) {
|
||||
return new String[] { "dev" };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.test.context.junit4.profile.resolver;
|
||||
|
||||
import org.springframework.test.context.ActiveProfilesResolver;
|
||||
|
||||
/**
|
||||
* @author Michail Nikolaev
|
||||
* @since 4.0
|
||||
*/
|
||||
public class ClassNameActiveProfilesResolver implements ActiveProfilesResolver {
|
||||
|
||||
@Override
|
||||
public String[] resolve(Class<?> testClass) {
|
||||
return new String[] { testClass.getSimpleName().toLowerCase() };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.test.context.junit4.profile.resolver;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Michail Nikolaev
|
||||
* @since 4.0
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
@ActiveProfiles(resolver = ClassNameActiveProfilesResolver.class)
|
||||
public class ClassNameActiveProfilesResolverTest {
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertTrue(Arrays.asList(applicationContext.getEnvironment().getActiveProfiles()).contains(
|
||||
getClass().getSimpleName().toLowerCase()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.test.context.junit4.profile.xml;
|
||||
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.ActiveProfilesResolver;
|
||||
|
||||
/**
|
||||
* @author Michail Nikolaev
|
||||
* @since 4.0
|
||||
*/
|
||||
@ActiveProfiles(resolver = DevProfileResolverXmlConfigTests.class, inheritProfiles = false)
|
||||
public class DevProfileResolverXmlConfigTests extends DevProfileXmlConfigTests implements ActiveProfilesResolver {
|
||||
|
||||
@Override
|
||||
public String[] resolve(Class<?> testClass) {
|
||||
return new String[] { "dev" };
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,7 +31,8 @@ import org.junit.runners.Suite.SuiteClasses;
|
||||
// Note: the following 'multi-line' layout is for enhanced code readability.
|
||||
@SuiteClasses({//
|
||||
DefaultProfileXmlConfigTests.class,//
|
||||
DevProfileXmlConfigTests.class //
|
||||
DevProfileXmlConfigTests.class,//
|
||||
DevProfileResolverXmlConfigTests.class //
|
||||
})
|
||||
public class ProfileXmlConfigTestSuite {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user