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:
parent
d4dcf4e4ec
commit
044f51283b
|
|
@ -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.
|
||||
|
|
@ -34,6 +34,7 @@ import java.lang.annotation.Target;
|
|||
* @see SmartContextLoader
|
||||
* @see MergedContextConfiguration
|
||||
* @see ContextConfiguration
|
||||
* @see ActiveProfilesResolver
|
||||
* @see org.springframework.context.ApplicationContext
|
||||
* @see org.springframework.context.annotation.Profile
|
||||
*/
|
||||
|
|
@ -47,8 +48,8 @@ public @interface ActiveProfiles {
|
|||
* Alias for {@link #profiles}.
|
||||
*
|
||||
* <p>This attribute may <strong>not</strong> be used in conjunction
|
||||
* with {@link #profiles}, but it may be used <em>instead</em> of
|
||||
* {@link #profiles}.
|
||||
* with {@link #profiles} or {@link #resolver}, but it may be used
|
||||
* <em>instead</em> of them.
|
||||
*/
|
||||
String[] value() default {};
|
||||
|
||||
|
|
@ -56,11 +57,24 @@ public @interface ActiveProfiles {
|
|||
* The bean definition profiles to activate.
|
||||
*
|
||||
* <p>This attribute may <strong>not</strong> be used in conjunction
|
||||
* with {@link #value}, but it may be used <em>instead</em> of
|
||||
* {@link #value}.
|
||||
* with {@link #value} or {@link #resolver}, but it may be used
|
||||
* <em>instead</em> of them.
|
||||
*/
|
||||
String[] profiles() default {};
|
||||
|
||||
/**
|
||||
* The type of {@link ActiveProfilesResolver} to use for resolving the active
|
||||
* bean definition profiles programmatically.
|
||||
*
|
||||
* <p>This attribute may <strong>not</strong> be used in conjunction
|
||||
* with {@link #profiles} or {@link #value}, but it may be used <em>instead</em>
|
||||
* of them in order to resolve the active profiles programmatically.
|
||||
*
|
||||
* @since 4.0
|
||||
* @see ActiveProfilesResolver
|
||||
*/
|
||||
Class<? extends ActiveProfilesResolver> resolver() default ActiveProfilesResolver.class;
|
||||
|
||||
/**
|
||||
* Whether or not bean definition profiles from superclasses should be
|
||||
* <em>inherited</em>.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Strategy interface for programmatically resolving which <em>active bean
|
||||
* definition profiles</em> should be used when loading an
|
||||
* {@link org.springframework.context.ApplicationContext ApplicationContext}
|
||||
* for a test class.
|
||||
*
|
||||
* <p>A custom {@code ActiveProfilesResolver} can be registered via the
|
||||
* {@link ActiveProfiles#resolver resolver} attribute of {@code @ActiveProfiles}.
|
||||
*
|
||||
* <p>Concrete implementations must provide a {@code public} no-args constructor.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @author Michail Nikolaev
|
||||
* @since 4.0
|
||||
* @see ActiveProfiles
|
||||
*/
|
||||
public interface ActiveProfilesResolver {
|
||||
|
||||
/**
|
||||
* Resolve the <em>bean definition profiles</em> to use when loading an
|
||||
* {@code ApplicationContext} for the given {@linkplain Class test class}.
|
||||
*
|
||||
* @param testClass the test class for which the profiles should be resolved;
|
||||
* never {@code null}
|
||||
* @return the list of bean definition profiles to use when loading the
|
||||
* {@code ApplicationContext}; never {@code null}
|
||||
* @see ActiveProfiles#resolver
|
||||
* @see ActiveProfiles#inheritProfiles
|
||||
*/
|
||||
String[] resolve(Class<?> testClass);
|
||||
|
||||
}
|
||||
|
|
@ -16,11 +16,6 @@
|
|||
|
||||
package org.springframework.test.context;
|
||||
|
||||
import static org.springframework.beans.BeanUtils.instantiateClass;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.findAnnotationDeclaringClass;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.findAnnotationDeclaringClassForTypes;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.isAnnotationDeclaredLocally;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -42,6 +37,9 @@ import org.springframework.util.ClassUtils;
|
|||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.springframework.beans.BeanUtils.*;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.*;
|
||||
|
||||
/**
|
||||
* Utility methods for working with {@link ContextLoader ContextLoaders} and
|
||||
* {@link SmartContextLoader SmartContextLoaders} and resolving resource locations,
|
||||
|
|
@ -49,12 +47,14 @@ import org.springframework.util.StringUtils;
|
|||
* initializers.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @author Michail Nikolaev
|
||||
* @since 3.1
|
||||
* @see ContextLoader
|
||||
* @see SmartContextLoader
|
||||
* @see ContextConfiguration
|
||||
* @see ContextConfigurationAttributes
|
||||
* @see ActiveProfiles
|
||||
* @see ActiveProfilesResolver
|
||||
* @see ApplicationContextInitializer
|
||||
* @see ContextHierarchy
|
||||
* @see MergedContextConfiguration
|
||||
|
|
@ -477,24 +477,43 @@ abstract class ContextLoaderUtils {
|
|||
|
||||
while (declaringClass != null) {
|
||||
ActiveProfiles annotation = declaringClass.getAnnotation(annotationType);
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace(String.format("Retrieved @ActiveProfiles [%s] for declaring class [%s].", annotation,
|
||||
declaringClass.getName()));
|
||||
}
|
||||
validateActiveProfilesConfiguration(declaringClass, annotation);
|
||||
|
||||
String[] profiles = annotation.profiles();
|
||||
String[] valueProfiles = annotation.value();
|
||||
Class<? extends ActiveProfilesResolver> resolverClass = annotation.resolver();
|
||||
|
||||
if (!ObjectUtils.isEmpty(valueProfiles) && !ObjectUtils.isEmpty(profiles)) {
|
||||
String msg = String.format("Test class [%s] has been configured with @ActiveProfiles' 'value' [%s] "
|
||||
+ "and 'profiles' [%s] attributes. Only one declaration of active bean "
|
||||
+ "definition profiles is permitted per @ActiveProfiles annotation.", declaringClass.getName(),
|
||||
ObjectUtils.nullSafeToString(valueProfiles), ObjectUtils.nullSafeToString(profiles));
|
||||
logger.error(msg);
|
||||
throw new IllegalStateException(msg);
|
||||
boolean resolverDeclared = !ActiveProfilesResolver.class.equals(resolverClass);
|
||||
boolean valueDeclared = !ObjectUtils.isEmpty(valueProfiles);
|
||||
|
||||
if (resolverDeclared) {
|
||||
ActiveProfilesResolver resolver = null;
|
||||
try {
|
||||
resolver = instantiateClass(resolverClass, ActiveProfilesResolver.class);
|
||||
}
|
||||
catch (Exception e) {
|
||||
String msg = String.format("Could not instantiate ActiveProfilesResolver of "
|
||||
+ "type [%s] for test class [%s].", resolverClass.getName(), declaringClass.getName());
|
||||
logger.error(msg);
|
||||
throw new IllegalStateException(msg, e);
|
||||
}
|
||||
|
||||
if (resolver != null) {
|
||||
profiles = resolver.resolve(declaringClass);
|
||||
if (profiles == null) {
|
||||
String msg = String.format(
|
||||
"ActiveProfilesResolver [%s] returned a null array of bean definition profiles.",
|
||||
resolverClass.getName());
|
||||
logger.error(msg);
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!ObjectUtils.isEmpty(valueProfiles)) {
|
||||
else if (valueDeclared) {
|
||||
profiles = valueProfiles;
|
||||
}
|
||||
|
||||
|
|
@ -511,6 +530,43 @@ abstract class ContextLoaderUtils {
|
|||
return StringUtils.toStringArray(activeProfiles);
|
||||
}
|
||||
|
||||
private static void validateActiveProfilesConfiguration(Class<?> declaringClass, ActiveProfiles annotation) {
|
||||
String[] valueProfiles = annotation.value();
|
||||
String[] profiles = annotation.profiles();
|
||||
Class<? extends ActiveProfilesResolver> resolverClass = annotation.resolver();
|
||||
boolean valueDeclared = !ObjectUtils.isEmpty(valueProfiles);
|
||||
boolean profilesDeclared = !ObjectUtils.isEmpty(profiles);
|
||||
boolean resolverDeclared = !ActiveProfilesResolver.class.equals(resolverClass);
|
||||
|
||||
String msg = null;
|
||||
|
||||
if (valueDeclared && profilesDeclared) {
|
||||
msg = String.format("Test class [%s] has been configured with @ActiveProfiles' 'value' [%s] "
|
||||
+ "and 'profiles' [%s] attributes. Only one declaration of active bean "
|
||||
+ "definition profiles is permitted per @ActiveProfiles annotation.", declaringClass.getName(),
|
||||
ObjectUtils.nullSafeToString(valueProfiles), ObjectUtils.nullSafeToString(profiles));
|
||||
}
|
||||
else if (valueDeclared && resolverDeclared) {
|
||||
msg = String.format("Test class [%s] has been configured with @ActiveProfiles' 'value' [%s] "
|
||||
+ "and 'resolver' [%s] attributes. Only one source of active bean "
|
||||
+ "definition profiles is permitted per @ActiveProfiles annotation, "
|
||||
+ "either declaritively or programmatically.", declaringClass.getName(),
|
||||
ObjectUtils.nullSafeToString(valueProfiles), resolverClass.getName());
|
||||
}
|
||||
else if (profilesDeclared && resolverDeclared) {
|
||||
msg = String.format("Test class [%s] has been configured with @ActiveProfiles' 'profiles' [%s] "
|
||||
+ "and 'resolver' [%s] attributes. Only one source of active bean "
|
||||
+ "definition profiles is permitted per @ActiveProfiles annotation, "
|
||||
+ "either declaritively or programmatically.", declaringClass.getName(),
|
||||
ObjectUtils.nullSafeToString(profiles), resolverClass.getName());
|
||||
}
|
||||
|
||||
if (msg != null) {
|
||||
logger.error(msg);
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the {@link MergedContextConfiguration merged context configuration} for
|
||||
* the supplied {@link Class testClass} and {@code defaultContextLoaderClassName},
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,7 +197,6 @@
|
|||
TestContext framework is agnostic of the actual testing framework in use,
|
||||
thus allowing instrumentation of tests in various environments including
|
||||
JUnit, TestNG, and so on.</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="integration-testing-goals">
|
||||
|
|
@ -444,13 +443,13 @@
|
|||
|
||||
<programlisting language="java"><emphasis role="bold">@ContextConfiguration</emphasis>("/test-config.xml")
|
||||
public class XmlApplicationContextTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<programlisting language="java"><emphasis role="bold">@ContextConfiguration</emphasis>(<emphasis
|
||||
role="bold">classes</emphasis> = TestConfig.class)
|
||||
public class ConfigClassApplicationContextTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para>As an alternative or in addition to declaring resource
|
||||
|
|
@ -462,7 +461,7 @@ public class ConfigClassApplicationContextTests {
|
|||
<programlisting language="java"><emphasis role="bold">@ContextConfiguration</emphasis>(<emphasis
|
||||
role="bold">initializers</emphasis> = CustomContextIntializer.class)
|
||||
public class ContextInitializerTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para><interfacename>@ContextConfiguration</interfacename> may
|
||||
|
|
@ -477,7 +476,7 @@ public class ContextInitializerTests {
|
|||
role="bold">locations</emphasis> = "/test-context.xml", <emphasis
|
||||
role="bold">loader</emphasis> = CustomContextLoader.class)
|
||||
public class CustomLoaderXmlApplicationContextTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<note>
|
||||
|
|
@ -514,7 +513,7 @@ public class CustomLoaderXmlApplicationContextTests {
|
|||
<programlisting language="java">@ContextConfiguration
|
||||
<emphasis role="bold">@WebAppConfiguration</emphasis>
|
||||
public class WebAppTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para>To override the default, specify a different base resource
|
||||
|
|
@ -527,7 +526,7 @@ public class WebAppTests {
|
|||
<programlisting language="java">@ContextConfiguration
|
||||
<emphasis role="bold">@WebAppConfiguration("classpath:test-web-resources")</emphasis>
|
||||
public class WebAppTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para>Note that <interfacename>@WebAppConfiguration</interfacename>
|
||||
|
|
@ -559,7 +558,7 @@ public class WebAppTests {
|
|||
@ContextConfiguration("/child-config.xml")
|
||||
})
|
||||
public class ContextHierarchyTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<programlisting language="java">@WebAppConfiguration
|
||||
|
|
@ -568,7 +567,7 @@ public class ContextHierarchyTests {
|
|||
@ContextConfiguration(classes = WebConfig.class)
|
||||
})
|
||||
public class WebIntegrationTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para>If you need to merge or override the configuration for a given
|
||||
|
|
@ -594,19 +593,24 @@ public class WebIntegrationTests {
|
|||
<programlisting language="java">@ContextConfiguration
|
||||
<emphasis role="bold">@ActiveProfiles</emphasis>("dev")
|
||||
public class DeveloperTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<programlisting language="java">@ContextConfiguration
|
||||
<emphasis role="bold">@ActiveProfiles</emphasis>({"dev", "integration"})
|
||||
public class DeveloperIntegrationTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<note>
|
||||
<para><interfacename>@ActiveProfiles</interfacename> provides
|
||||
support for <emphasis>inheriting</emphasis> active bean definition
|
||||
profiles declared by superclasses by default.</para>
|
||||
profiles declared by superclasses by default. It is also possible
|
||||
to resolve active bean definition profiles programmatically by
|
||||
implementing a custom
|
||||
<interfacename>ActiveProfilesResolver</interfacename> and
|
||||
registering it via the <varname>resolver</varname> attribute of
|
||||
<interfacename>@ActiveProfiles</interfacename>.</para>
|
||||
</note>
|
||||
|
||||
<para>See <xref linkend="testcontext-ctx-management-env-profiles"/>
|
||||
|
|
@ -649,19 +653,20 @@ public class DeveloperIntegrationTests {
|
|||
|
||||
<programlisting language="java"><emphasis role="bold">@DirtiesContext</emphasis>
|
||||
public class ContextDirtyingTests {
|
||||
<lineannotation>// some tests that result in the Spring container being dirtied</lineannotation>
|
||||
// some tests that result in the Spring container being dirtied
|
||||
}</programlisting>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>After each test method in the current test class, when
|
||||
declared on a class with class mode set to
|
||||
<literal>AFTER_EACH_TEST_METHOD.</literal><programlisting
|
||||
language="java"><emphasis role="bold">@DirtiesContext</emphasis>(<emphasis
|
||||
role="bold">classMode</emphasis> = ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
<literal>AFTER_EACH_TEST_METHOD.</literal></para>
|
||||
|
||||
<programlisting language="java"><emphasis role="bold">@DirtiesContext</emphasis>(<emphasis
|
||||
role="bold">classMode</emphasis> = ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
public class ContextDirtyingTests {
|
||||
<lineannotation>// some tests that result in the Spring container being dirtied</lineannotation>
|
||||
}</programlisting></para>
|
||||
// some tests that result in the Spring container being dirtied
|
||||
}</programlisting>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
|
|
@ -670,7 +675,7 @@ public class ContextDirtyingTests {
|
|||
<programlisting language="java"><emphasis role="bold">@DirtiesContext</emphasis>
|
||||
@Test
|
||||
public void testProcessWhichDirtiesAppCtx() {
|
||||
<lineannotation>// some logic that results in the Spring container being dirtied</lineannotation>
|
||||
// some logic that results in the Spring container being dirtied
|
||||
}</programlisting>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
|
@ -696,7 +701,7 @@ public void testProcessWhichDirtiesAppCtx() {
|
|||
@ContextConfiguration("/child-config.xml")
|
||||
})
|
||||
public class BaseTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}
|
||||
|
||||
public class ExtendedTests extends BaseTests {
|
||||
|
|
@ -704,7 +709,7 @@ public class ExtendedTests extends BaseTests {
|
|||
@Test
|
||||
@DirtiesContext(<emphasis role="bold">hierarchyMode = HierarchyMode.CURRENT_LEVEL</emphasis>)
|
||||
public void test() {
|
||||
<lineannotation>// some logic that results in the child context being dirtied</lineannotation>
|
||||
// some logic that results in the child context being dirtied
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
|
|
@ -729,7 +734,7 @@ public class ExtendedTests extends BaseTests {
|
|||
<programlisting language="java">@ContextConfiguration
|
||||
<emphasis role="bold">@TestExecutionListeners</emphasis>({CustomTestExecutionListener.class, AnotherTestExecutionListener.class})
|
||||
public class CustomTestExecutionListenerTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para><interfacename>@TestExecutionListeners</interfacename>
|
||||
|
|
@ -761,7 +766,7 @@ public class CustomTestExecutionListenerTests {
|
|||
<emphasis role="bold">@TransactionConfiguration</emphasis>(<emphasis role="bold">transactionManager</emphasis> = "txMgr", <emphasis
|
||||
role="bold">defaultRollback</emphasis> = false)
|
||||
public class CustomConfiguredTransactionalTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<note>
|
||||
|
|
@ -793,7 +798,7 @@ public class CustomConfiguredTransactionalTests {
|
|||
<programlisting language="java"><emphasis role="bold">@Rollback</emphasis>(false)
|
||||
@Test
|
||||
public void testProcessWithoutRollback() {
|
||||
<lineannotation>// ...</lineannotation>
|
||||
// ...
|
||||
}</programlisting>
|
||||
</listitem>
|
||||
|
||||
|
|
@ -809,7 +814,7 @@ public void testProcessWithoutRollback() {
|
|||
|
||||
<programlisting language="java"><emphasis role="bold">@BeforeTransaction
|
||||
</emphasis>public void beforeTransaction() {
|
||||
<lineannotation>// logic to be executed before a transaction is started</lineannotation>
|
||||
// logic to be executed before a transaction is started
|
||||
}</programlisting>
|
||||
</listitem>
|
||||
|
||||
|
|
@ -825,7 +830,7 @@ public void testProcessWithoutRollback() {
|
|||
|
||||
<programlisting language="java"><emphasis role="bold">@AfterTransaction
|
||||
</emphasis>public void afterTransaction() {
|
||||
<lineannotation>// logic to be executed after a transaction has ended</lineannotation>
|
||||
// logic to be executed after a transaction has ended
|
||||
}</programlisting>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
|
@ -944,7 +949,7 @@ public void testProcessWithoutRollback() {
|
|||
role="bold">name</emphasis>="java.vendor", <emphasis role="bold">value</emphasis>="Sun Microsystems Inc.")
|
||||
@Test
|
||||
public void testProcessWhichRunsOnlyOnSunJvm() {
|
||||
<lineannotation>// some logic that should run only on Java VMs from Sun Microsystems</lineannotation>
|
||||
// some logic that should run only on Java VMs from Sun Microsystems
|
||||
}</programlisting>
|
||||
|
||||
<para>Alternatively, you can configure
|
||||
|
|
@ -957,7 +962,7 @@ public void testProcessWhichRunsOnlyOnSunJvm() {
|
|||
role="bold">name</emphasis>="test-groups", <emphasis role="bold">values</emphasis>={"unit-tests", "integration-tests"})
|
||||
@Test
|
||||
public void testProcessWhichRunsForUnitOrIntegrationTestGroups() {
|
||||
<lineannotation>// some logic that should run only for unit and integration test groups</lineannotation>
|
||||
// some logic that should run only for unit and integration test groups
|
||||
}</programlisting>
|
||||
</listitem>
|
||||
|
||||
|
|
@ -977,7 +982,7 @@ public void testProcessWhichRunsForUnitOrIntegrationTestGroups() {
|
|||
|
||||
<programlisting language="java"><emphasis role="bold">@ProfileValueSourceConfiguration</emphasis>(CustomProfileValueSource.class)
|
||||
public class CustomProfileValueSourceTests {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
</listitem>
|
||||
|
||||
|
|
@ -997,7 +1002,7 @@ public class CustomProfileValueSourceTests {
|
|||
|
||||
<programlisting language="java"><emphasis role="bold">@Timed</emphasis>(millis=1000)
|
||||
public void testProcessWithOneSecondTimeout() {
|
||||
<lineannotation>// some logic that should not take longer than 1 second to execute</lineannotation>
|
||||
// some logic that should not take longer than 1 second to execute
|
||||
}</programlisting>
|
||||
|
||||
<para>Spring's <interfacename>@Timed</interfacename> annotation has
|
||||
|
|
@ -1030,7 +1035,7 @@ public void testProcessWithOneSecondTimeout() {
|
|||
<programlisting language="java"><emphasis role="bold">@Repeat</emphasis>(10)
|
||||
@Test
|
||||
public void testProcessRepeatedly() {
|
||||
<lineannotation>// ...</lineannotation>
|
||||
// ...
|
||||
}</programlisting>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
|
@ -1286,7 +1291,7 @@ public class MyTest {
|
|||
<emphasis role="bold">@Autowired</emphasis>
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para>Similarly, if your test is configured to load a
|
||||
|
|
@ -1301,7 +1306,7 @@ public class MyWebAppTest {
|
|||
<emphasis role="bold">@Autowired</emphasis>
|
||||
private WebApplicationContext wac;
|
||||
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para>Dependency injection via
|
||||
|
|
@ -1355,11 +1360,11 @@ public class MyWebAppTest {
|
|||
is</emphasis>.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from "/app-config.xml" and
|
||||
// "/test-config.xml" in the root of the classpath</lineannotation>
|
||||
// ApplicationContext will be loaded from "/app-config.xml" and
|
||||
// "/test-config.xml" in the root of the classpath
|
||||
<emphasis role="bold">@ContextConfiguration(locations={"/app-config.xml", "/test-config.xml"})</emphasis>
|
||||
public class MyTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para><interfacename>@ContextConfiguration</interfacename> supports an
|
||||
|
|
@ -1374,7 +1379,7 @@ public class MyTest {
|
|||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<emphasis role="bold">@ContextConfiguration({"/app-config.xml", "/test-config.xml"})</emphasis>
|
||||
public class MyTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para>If you omit both the <varname>locations</varname> and
|
||||
|
|
@ -1391,11 +1396,11 @@ public class MyTest {
|
|||
<programlisting language="java">package com.example;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from
|
||||
// "classpath:/com/example/MyTest-context.xml"</lineannotation>
|
||||
// ApplicationContext will be loaded from
|
||||
// "classpath:/com/example/MyTest-context.xml"
|
||||
<emphasis role="bold">@ContextConfiguration</emphasis>
|
||||
public class MyTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
</section>
|
||||
|
||||
|
|
@ -1410,10 +1415,10 @@ public class MyTest {
|
|||
references to annotated classes.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from AppConfig and TestConfig</lineannotation>
|
||||
// ApplicationContext will be loaded from AppConfig and TestConfig
|
||||
<emphasis role="bold">@ContextConfiguration(classes = {AppConfig.class, TestConfig.class})</emphasis>
|
||||
public class MyTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para>If you omit the <varname>classes</varname> attribute from the
|
||||
|
|
@ -1433,19 +1438,19 @@ public class MyTest {
|
|||
configuration class if desired.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from the
|
||||
// static inner Config class</lineannotation>
|
||||
// ApplicationContext will be loaded from the
|
||||
// static inner Config class
|
||||
<emphasis role="bold">@ContextConfiguration</emphasis>
|
||||
public class OrderServiceTest {
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
<lineannotation>// this bean will be injected into the OrderServiceTest class</lineannotation>
|
||||
// this bean will be injected into the OrderServiceTest class
|
||||
@Bean
|
||||
public OrderService orderService() {
|
||||
OrderService orderService = new OrderServiceImpl();
|
||||
<lineannotation>// set properties, etc.</lineannotation>
|
||||
// set properties, etc.
|
||||
return orderService;
|
||||
}
|
||||
}
|
||||
|
|
@ -1455,7 +1460,7 @@ public class OrderServiceTest {
|
|||
|
||||
@Test
|
||||
public void testOrderService() {
|
||||
<lineannotation>// test the orderService</lineannotation>
|
||||
// test the orderService
|
||||
}
|
||||
|
||||
}</programlisting>
|
||||
|
|
@ -1520,13 +1525,13 @@ public class OrderServiceTest {
|
|||
Spring's <interfacename>@Order</interfacename> annotation.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from TestConfig
|
||||
</lineannotation><lineannotation>// and initialized by TestAppCtxInitializer</lineannotation>
|
||||
// ApplicationContext will be loaded from TestConfig
|
||||
// and initialized by TestAppCtxInitializer
|
||||
<emphasis role="bold">@ContextConfiguration(
|
||||
classes = TestConfig.class,
|
||||
initializers = TestAppCtxInitializer.class)</emphasis>
|
||||
public class MyTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para>It is also possible to omit the declaration of XML configuration
|
||||
|
|
@ -1539,11 +1544,11 @@ public class MyTest {
|
|||
or configuration classes.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be initialized by EntireAppInitializer
|
||||
</lineannotation><lineannotation>// which presumably registers beans in the context</lineannotation>
|
||||
// ApplicationContext will be initialized by EntireAppInitializer
|
||||
// which presumably registers beans in the context
|
||||
<emphasis role="bold">@ContextConfiguration(initializers = EntireAppInitializer.class)</emphasis>
|
||||
public class MyTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
</section>
|
||||
|
||||
|
|
@ -1585,18 +1590,18 @@ public class MyTest {
|
|||
<emphasis>"base-config.xml"</emphasis>.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from "/base-config.xml"
|
||||
// in the root of the classpath</lineannotation>
|
||||
// ApplicationContext will be loaded from "/base-config.xml"
|
||||
// in the root of the classpath
|
||||
<emphasis role="bold">@ContextConfiguration("/base-config.xml")</emphasis>
|
||||
public class BaseTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}
|
||||
|
||||
<lineannotation>// ApplicationContext will be loaded from "/base-config.xml" and
|
||||
// "/extended-config.xml" </lineannotation><lineannotation>in the root of the classpath</lineannotation>
|
||||
// ApplicationContext will be loaded from "/base-config.xml" and
|
||||
// "/extended-config.xml" in the root of the classpath
|
||||
<emphasis role="bold">@ContextConfiguration("/extended-config.xml")</emphasis>
|
||||
public class ExtendedTest extends BaseTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para>Similarly, in the following example that uses annotated classes,
|
||||
|
|
@ -1609,16 +1614,16 @@ public class ExtendedTest extends BaseTest {
|
|||
<classname>BaseConfig</classname>.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be loaded from BaseConfig</lineannotation>
|
||||
// ApplicationContext will be loaded from BaseConfig
|
||||
<emphasis role="bold">@ContextConfiguration(classes = BaseConfig.class)</emphasis>
|
||||
public class BaseTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}
|
||||
|
||||
<lineannotation>// ApplicationContext will be loaded from BaseConfig and ExtendedConfig</lineannotation>
|
||||
// ApplicationContext will be loaded from BaseConfig and ExtendedConfig
|
||||
<emphasis role="bold">@ContextConfiguration(classes = ExtendedConfig.class)</emphasis>
|
||||
public class ExtendedTest extends BaseTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
|
||||
<para>In the following example that uses context initializers, the
|
||||
|
|
@ -1632,17 +1637,17 @@ public class ExtendedTest extends BaseTest {
|
|||
Spring's <interfacename>@Order</interfacename> annotation.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// ApplicationContext will be initialized by BaseInitializer</lineannotation>
|
||||
// ApplicationContext will be initialized by BaseInitializer
|
||||
<emphasis role="bold">@ContextConfiguration(initializers=BaseInitializer.class)</emphasis>
|
||||
public class BaseTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}
|
||||
|
||||
<lineannotation>// ApplicationContext will be initialized by BaseInitializer
|
||||
// and ExtendedInitializer</lineannotation>
|
||||
// ApplicationContext will be initialized by BaseInitializer
|
||||
// and ExtendedInitializer
|
||||
<emphasis role="bold">@ContextConfiguration(initializers=ExtendedInitializer.class)</emphasis>
|
||||
public class ExtendedTest extends BaseTest {
|
||||
<lineannotation>// class body...</lineannotation>
|
||||
// class body...
|
||||
}</programlisting>
|
||||
</section>
|
||||
|
||||
|
|
@ -1814,7 +1819,7 @@ public class TransferServiceTest {
|
|||
|
||||
@Test
|
||||
public void testTransferService() {
|
||||
// test the transferService
|
||||
// test the transferService
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
|
|
@ -1849,7 +1854,113 @@ public class TransferServiceTest {
|
|||
<interfacename>@ContextConfiguration </interfacename>annotation. The
|
||||
body of the test class itself remains completely unchanged.</para>
|
||||
|
||||
<!-- TODO Consider documenting inheritance for active profiles. -->
|
||||
<para>It is often the case that a single set of profiles is used
|
||||
across multiple test classes within a given project. Thus, to avoid
|
||||
duplicate declarations of the
|
||||
<interfacename>@ActiveProfiles</interfacename> annotation it is
|
||||
possible to declare <interfacename>@ActiveProfiles</interfacename>
|
||||
once on a base class, and subclasses will automatically inherit the
|
||||
<interfacename>@ActiveProfiles</interfacename> configuration from the
|
||||
base class. In the following example, the declaration of
|
||||
<interfacename>@ActiveProfiles</interfacename> (as well as other
|
||||
annotations) has been moved to an abstract superclass,
|
||||
<classname>AbstractIntegrationTest</classname>.</para>
|
||||
|
||||
<programlisting language="java">package com.bank.service;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(
|
||||
classes = {
|
||||
TransferServiceConfig.class,
|
||||
StandaloneDataConfig.class,
|
||||
JndiDataConfig.class})
|
||||
@ActiveProfiles("dev")
|
||||
public abstract class AbstractIntegrationTest {
|
||||
}</programlisting>
|
||||
|
||||
<programlisting language="java">package com.bank.service;
|
||||
|
||||
// "dev" profile inherited from superclass
|
||||
public class TransferServiceTest extends AbstractIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private TransferService transferService;
|
||||
|
||||
@Test
|
||||
public void testTransferService() {
|
||||
// test the transferService
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para><interfacename>@ActiveProfiles</interfacename> also supports an
|
||||
<methodname>inheritProfiles</methodname> attribute that can be used to
|
||||
disable the inheritance of active profiles.</para>
|
||||
|
||||
<programlisting language="java">package com.bank.service;
|
||||
|
||||
// "dev" profile overridden with "production"
|
||||
@ActiveProfiles(profiles = "production", inheritProfiles = false)
|
||||
public class ProductionTransferServiceTest extends AbstractIntegrationTest {
|
||||
// test body
|
||||
}</programlisting>
|
||||
|
||||
<para>Furthermore, it is sometimes necessary to resolve active
|
||||
profiles for tests <emphasis>programmatically</emphasis> instead of
|
||||
declaratively — for example, based on:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>the current operating system</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>whether tests are being executed on a continuous integration
|
||||
build server</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>the presence of certain environment variables</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>the presence of custom class-level annotations</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>etc.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>To resolve active bean definition profiles programmatically,
|
||||
simply implement a custom
|
||||
<interfacename>ActiveProfilesResolver</interfacename> and register it
|
||||
via the <varname>resolver</varname> attribute of
|
||||
<interfacename>@ActiveProfiles</interfacename>. The following example
|
||||
demonstrates how to implement and register a custom
|
||||
<classname>OperatingSystemActiveProfilesResolver</classname>. For
|
||||
further information, refer to the respective Javadoc.</para>
|
||||
|
||||
<programlisting language="java">package com.bank.service;
|
||||
|
||||
// "dev" profile overridden programmatically via a custom resolver
|
||||
@ActiveProfiles(
|
||||
resolver = OperatingSystemActiveProfilesResolver.class,
|
||||
inheritProfiles = false)
|
||||
public class TransferServiceTest extends AbstractIntegrationTest {
|
||||
// test body
|
||||
}</programlisting>
|
||||
|
||||
<programlisting language="java">package com.bank.service.test;
|
||||
|
||||
public class OperatingSystemActiveProfilesResolver implements ActiveProfilesResolver {
|
||||
|
||||
@Override
|
||||
String[] resolve(Class<?> testClass) {
|
||||
String profile = ...;
|
||||
// determine the value of profile based on the operating system
|
||||
return new String[] {profile};
|
||||
}
|
||||
}</programlisting>
|
||||
</section>
|
||||
|
||||
<section xml:id="testcontext-ctx-management-web">
|
||||
|
|
@ -2416,11 +2527,11 @@ public class ExtendedTests extends BaseTests {}</programlisting>
|
|||
injection.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// specifies the Spring configuration to load for this test fixture</lineannotation>
|
||||
// specifies the Spring configuration to load for this test fixture
|
||||
<emphasis role="bold">@ContextConfiguration("repository-config.xml")</emphasis>
|
||||
public class HibernateTitleRepositoryTests {
|
||||
|
||||
<lineannotation>// this instance will be dependency injected by type</lineannotation>
|
||||
// this instance will be dependency injected by type
|
||||
<emphasis role="bold">@Autowired</emphasis>
|
||||
private HibernateTitleRepository titleRepository;
|
||||
|
||||
|
|
@ -2436,11 +2547,11 @@ public class HibernateTitleRepositoryTests {
|
|||
below.</para>
|
||||
|
||||
<programlisting language="java">@RunWith(SpringJUnit4ClassRunner.class)
|
||||
<lineannotation>// specifies the Spring configuration to load for this test fixture</lineannotation>
|
||||
// specifies the Spring configuration to load for this test fixture
|
||||
<emphasis role="bold">@ContextConfiguration("repository-config.xml")</emphasis>
|
||||
public class HibernateTitleRepositoryTests {
|
||||
|
||||
<lineannotation>// this instance will be dependency injected by type</lineannotation>
|
||||
// this instance will be dependency injected by type
|
||||
private HibernateTitleRepository titleRepository;
|
||||
|
||||
<emphasis role="bold">@Autowired</emphasis>
|
||||
|
|
@ -2490,7 +2601,7 @@ public class HibernateTitleRepositoryTests {
|
|||
specific target bean as follows, but make sure to delegate to the
|
||||
overridden method in the superclass as well.</para>
|
||||
|
||||
<programlisting language="java"><lineannotation>// ...</lineannotation>
|
||||
<programlisting language="java">// ...
|
||||
|
||||
@Autowired
|
||||
@Override
|
||||
|
|
@ -2498,7 +2609,7 @@ public class HibernateTitleRepositoryTests {
|
|||
<emphasis role="bold">super</emphasis>.setDataSource(dataSource);
|
||||
}
|
||||
|
||||
<lineannotation>// ...</lineannotation></programlisting>
|
||||
// ...</programlisting>
|
||||
|
||||
<para>The specified qualifier value indicates the specific
|
||||
<interfacename>DataSource</interfacename> bean to inject, narrowing
|
||||
|
|
@ -2749,29 +2860,29 @@ public class FictitiousTransactionalTest {
|
|||
|
||||
<emphasis role="bold">@BeforeTransaction</emphasis>
|
||||
public void verifyInitialDatabaseState() {
|
||||
<lineannotation>// logic to verify the initial state before a transaction is started</lineannotation>
|
||||
// logic to verify the initial state before a transaction is started
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUpTestDataWithinTransaction() {
|
||||
<lineannotation>// set up test data within the transaction</lineannotation>
|
||||
// set up test data within the transaction
|
||||
}
|
||||
|
||||
@Test
|
||||
<lineannotation>// overrides the class-level defaultRollback setting</lineannotation>
|
||||
// overrides the class-level defaultRollback setting
|
||||
<emphasis role="bold">@Rollback(true)</emphasis>
|
||||
public void modifyDatabaseWithinTransaction() {
|
||||
<lineannotation>// logic which uses the test data and modifies database state</lineannotation>
|
||||
// logic which uses the test data and modifies database state
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDownWithinTransaction() {
|
||||
<lineannotation>// execute "tear down" logic within the transaction</lineannotation>
|
||||
// execute "tear down" logic within the transaction
|
||||
}
|
||||
|
||||
<emphasis role="bold">@AfterTransaction</emphasis>
|
||||
public void verifyFinalDatabaseState() {
|
||||
<lineannotation>// logic to verify the final state after transaction has rolled back</lineannotation>
|
||||
// logic to verify the final state after transaction has rolled back
|
||||
}
|
||||
|
||||
}</programlisting>
|
||||
|
|
@ -2793,7 +2904,7 @@ public class FictitiousTransactionalTest {
|
|||
frameworks that maintain an in-memory <emphasis>unit of
|
||||
work</emphasis>.</para>
|
||||
|
||||
<programlisting language="java"><lineannotation>// ...</lineannotation>
|
||||
<programlisting language="java">// ...
|
||||
|
||||
@Autowired
|
||||
private SessionFactory sessionFactory;
|
||||
|
|
@ -2812,7 +2923,7 @@ public void updateWithSessionFlush() {
|
|||
sessionFactory.getCurrentSession().flush();
|
||||
}
|
||||
|
||||
<lineannotation>// ...</lineannotation></programlisting>
|
||||
// ...</programlisting>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
|
|
@ -2922,7 +3033,7 @@ public class SimpleTest {
|
|||
|
||||
@Test
|
||||
public void testMethod() {
|
||||
<lineannotation>// execute test logic...</lineannotation>
|
||||
// execute test logic...
|
||||
}
|
||||
}</programlisting>
|
||||
</section>
|
||||
|
|
@ -3226,8 +3337,7 @@ public class MyWebTests {
|
|||
|
||||
<programlisting language="xml"><bean id="accountService" class="org.mockito.Mockito" factory-method="mock">
|
||||
<constructor-arg value="org.example.AccountService"/>
|
||||
</bean>
|
||||
</programlisting>
|
||||
</bean></programlisting>
|
||||
|
||||
<para>Then you can inject the mock service into the test in order set
|
||||
up and verify expectations:</para>
|
||||
|
|
@ -3274,26 +3384,22 @@ public class AccountTests {
|
|||
additional builder-style methods corresponding to properties of
|
||||
<classname>MockHttpServletRequest</classname>. For example:</para>
|
||||
|
||||
<programlisting language="java">mockMvc.perform(post("/hotels/{id}", 42).accept(MediaType.APPLICATION_JSON));
|
||||
</programlisting>
|
||||
<programlisting language="java">mockMvc.perform(post("/hotels/{id}", 42).accept(MediaType.APPLICATION_JSON));</programlisting>
|
||||
|
||||
<para>In addition to all the HTTP methods, you can also perform file
|
||||
upload requests, which internally creates an instance of
|
||||
<classname>MockMultipartHttpServletRequest</classname>:</para>
|
||||
|
||||
<programlisting language="java">mockMvc.perform(fileUpload("/doc").file("a1", "ABC".getBytes("UTF-8")));
|
||||
</programlisting>
|
||||
<programlisting language="java">mockMvc.perform(fileUpload("/doc").file("a1", "ABC".getBytes("UTF-8")));</programlisting>
|
||||
|
||||
<para>Query string parameters can be specified in the URI
|
||||
template:</para>
|
||||
|
||||
<programlisting language="java">mockMvc.perform(get("/hotels?foo={foo}", "bar"));
|
||||
</programlisting>
|
||||
<programlisting language="java">mockMvc.perform(get("/hotels?foo={foo}", "bar"));</programlisting>
|
||||
|
||||
<para>Or by adding Servlet request parameters:</para>
|
||||
|
||||
<programlisting language="java">mockMvc.perform(get("/hotels").param("foo", "bar"));
|
||||
</programlisting>
|
||||
<programlisting language="java">mockMvc.perform(get("/hotels").param("foo", "bar"));</programlisting>
|
||||
|
||||
<para>If application code relies on Servlet request parameters, and
|
||||
doesn't check the query string, as is most often the case, then it
|
||||
|
|
@ -3308,8 +3414,7 @@ public class AccountTests {
|
|||
<function>servletPath</function> accordingly so that request mappings
|
||||
will work:</para>
|
||||
|
||||
<programlisting language="java">mockMvc.perform(get("/app/main/hotels/{id}").contextPath("/app").servletPath("/main"))
|
||||
</programlisting>
|
||||
<programlisting language="java">mockMvc.perform(get("/app/main/hotels/{id}").contextPath("/app").servletPath("/main"))</programlisting>
|
||||
|
||||
<para>Looking at the above example, it would be cumbersome to set the
|
||||
contextPath and servletPath with every performed request. That's why
|
||||
|
|
@ -3326,9 +3431,7 @@ public class AccountTests {
|
|||
.defaultRequest(get("/")
|
||||
.contextPath("/app").servletPath("/main")
|
||||
.accept(MediaType.APPLICATION_JSON).build();
|
||||
}
|
||||
|
||||
}</programlisting>
|
||||
}</programlisting>
|
||||
|
||||
<para>The above properties will apply to every request performed
|
||||
through the <classname>MockMvc</classname>. If the same property is
|
||||
|
|
@ -3345,8 +3448,7 @@ public class AccountTests {
|
|||
<function>.andExpect(..)</function> after call to perform the
|
||||
request:</para>
|
||||
|
||||
<programlisting language="java">mockMvc.perform(get("/accounts/1")).andExpect(status().isOk());
|
||||
</programlisting>
|
||||
<programlisting language="java">mockMvc.perform(get("/accounts/1")).andExpect(status().isOk());</programlisting>
|
||||
|
||||
<para><literal>MockMvcResultMatchers.*</literal> defines a number of
|
||||
static members, some of which return types with additional methods,
|
||||
|
|
@ -3369,8 +3471,7 @@ public class AccountTests {
|
|||
<programlisting language="java">
|
||||
mockMvc.perform(post("/persons"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(model().attributeHasErrors("person"));
|
||||
</programlisting>
|
||||
.andExpect(model().attributeHasErrors("person"));</programlisting>
|
||||
|
||||
<para>Many times when writing tests, it's useful to dump the result of
|
||||
the performed request. This can be done as follows, where
|
||||
|
|
@ -3518,7 +3619,7 @@ mockServer.verify();</programlisting>
|
|||
shown below:</para>
|
||||
|
||||
<programlisting language="java">import static org.junit.Assert.assertEquals;
|
||||
<lineannotation>// import ...</lineannotation>
|
||||
// import ...
|
||||
|
||||
<emphasis role="bold">@ContextConfiguration</emphasis>
|
||||
public abstract class AbstractClinicTests <emphasis role="bold">extends AbstractTransactionalJUnit4SpringContextTests</emphasis> {
|
||||
|
|
@ -3535,10 +3636,10 @@ public abstract class AbstractClinicTests <emphasis role="bold">extends Abstract
|
|||
assertEquals("Leary", v1.getLastName());
|
||||
assertEquals(1, v1.getNrOfSpecialties());
|
||||
assertEquals("radiology", (v1.getSpecialties().get(0)).getName());
|
||||
<lineannotation>// ...</lineannotation>
|
||||
// ...
|
||||
}
|
||||
|
||||
<lineannotation>// ...</lineannotation>
|
||||
// ...
|
||||
}</programlisting>
|
||||
|
||||
<para>Notes:</para>
|
||||
|
|
@ -3608,8 +3709,7 @@ public abstract class AbstractClinicTests <emphasis role="bold">extends Abstract
|
|||
<literal>AbstractClinicTests-context.xml</literal>.</para>
|
||||
|
||||
<programlisting language="java"><emphasis role="bold">@ContextConfiguration</emphasis>
|
||||
public class HibernateClinicTests extends AbstractClinicTests { }
|
||||
</programlisting>
|
||||
public class HibernateClinicTests extends AbstractClinicTests { }</programlisting>
|
||||
|
||||
<para>In a large-scale application, the Spring configuration is often
|
||||
split across multiple files. Consequently, configuration locations are
|
||||
|
|
|
|||
Loading…
Reference in New Issue