下面列出了怎么用org.springframework.test.context.MergedContextConfiguration的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Introduced to investigate claims made in a discussion on
* <a href="http://stackoverflow.com/questions/24725438/what-could-cause-a-class-implementing-applicationlistenercontextrefreshedevent">Stack Overflow</a>.
*/
@Test
public void buildMergedConfigWithAtWebAppConfigurationWithAnnotationAndClassesOnSuperclass() {
Class<?> webTestClass = WebClassesFoo.class;
Class<?> standardTestClass = ClassesFoo.class;
WebMergedContextConfiguration webMergedConfig = (WebMergedContextConfiguration) buildMergedContextConfiguration(webTestClass);
MergedContextConfiguration standardMergedConfig = buildMergedContextConfiguration(standardTestClass);
assertEquals(webMergedConfig, webMergedConfig);
assertEquals(standardMergedConfig, standardMergedConfig);
assertNotEquals(standardMergedConfig, webMergedConfig);
assertNotEquals(webMergedConfig, standardMergedConfig);
assertMergedConfig(webMergedConfig, webTestClass, EMPTY_STRING_ARRAY, new Class<?>[] { FooConfig.class },
WebDelegatingSmartContextLoader.class);
assertMergedConfig(standardMergedConfig, standardTestClass, EMPTY_STRING_ARRAY,
new Class<?>[] { FooConfig.class }, DelegatingSmartContextLoader.class);
}
/**
* Introduced to investigate claims made in a discussion on
* <a href="http://stackoverflow.com/questions/24725438/what-could-cause-a-class-implementing-applicationlistenercontextrefreshedevent">Stack Overflow</a>.
*/
@Test
public void buildMergedConfigWithAtWebAppConfigurationWithAnnotationAndClassesOnSuperclass() {
Class<?> webTestClass = WebClassesFoo.class;
Class<?> standardTestClass = ClassesFoo.class;
WebMergedContextConfiguration webMergedConfig = (WebMergedContextConfiguration) buildMergedContextConfiguration(webTestClass);
MergedContextConfiguration standardMergedConfig = buildMergedContextConfiguration(standardTestClass);
assertEquals(webMergedConfig, webMergedConfig);
assertEquals(standardMergedConfig, standardMergedConfig);
assertNotEquals(standardMergedConfig, webMergedConfig);
assertNotEquals(webMergedConfig, standardMergedConfig);
assertMergedConfig(webMergedConfig, webTestClass, EMPTY_STRING_ARRAY, array(FooConfig.class),
WebDelegatingSmartContextLoader.class);
assertMergedConfig(standardMergedConfig, standardTestClass, EMPTY_STRING_ARRAY,
array(FooConfig.class), DelegatingSmartContextLoader.class);
}
/**
* {@inheritDoc}
*/
@Override
public void put(MergedContextConfiguration key, ApplicationContext context) {
Assert.notNull(key, "Key must not be null");
Assert.notNull(context, "ApplicationContext must not be null");
this.contextMap.put(key, context);
MergedContextConfiguration child = key;
MergedContextConfiguration parent = child.getParent();
while (parent != null) {
Set<MergedContextConfiguration> list = this.hierarchyMap.computeIfAbsent(parent, k -> new HashSet<>());
list.add(child);
child = parent;
parent = child.getParent();
}
}
private void remove(List<MergedContextConfiguration> removedContexts, MergedContextConfiguration key) {
Assert.notNull(key, "Key must not be null");
Set<MergedContextConfiguration> children = this.hierarchyMap.get(key);
if (children != null) {
for (MergedContextConfiguration child : children) {
// Recurse through lower levels
remove(removedContexts, child);
}
// Remove the set of children for the current context from the hierarchy map.
this.hierarchyMap.remove(key);
}
// Physically remove and close leaf nodes first (i.e., on the way back up the
// stack as opposed to prior to the recursive call).
ApplicationContext context = this.contextMap.remove(key);
if (context instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) context).close();
}
removedContexts.add(key);
}
private void remove(List<MergedContextConfiguration> removedContexts, MergedContextConfiguration key) {
Assert.notNull(key, "Key must not be null");
Set<MergedContextConfiguration> children = this.hierarchyMap.get(key);
if (children != null) {
for (MergedContextConfiguration child : children) {
// Recurse through lower levels
remove(removedContexts, child);
}
// Remove the set of children for the current context from the hierarchy map.
this.hierarchyMap.remove(key);
}
// Physically remove and close leaf nodes first (i.e., on the way back up the
// stack as opposed to prior to the recursive call).
ApplicationContext context = this.contextMap.remove(key);
if (context instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) context).close();
}
removedContexts.add(key);
}
void assertMergedConfig(
MergedContextConfiguration mergedConfig,
Class<?> expectedTestClass,
String[] expectedLocations,
Class<?>[] expectedClasses,
Set<Class<? extends ApplicationContextInitializer<?>>> expectedInitializerClasses,
Class<? extends ContextLoader> expectedContextLoaderClass) {
assertNotNull(mergedConfig);
assertEquals(expectedTestClass, mergedConfig.getTestClass());
assertNotNull(mergedConfig.getLocations());
assertArrayEquals(expectedLocations, mergedConfig.getLocations());
assertNotNull(mergedConfig.getClasses());
assertArrayEquals(expectedClasses, mergedConfig.getClasses());
assertNotNull(mergedConfig.getActiveProfiles());
if (expectedContextLoaderClass == null) {
assertNull(mergedConfig.getContextLoader());
}
else {
assertEquals(expectedContextLoaderClass, mergedConfig.getContextLoader().getClass());
}
assertNotNull(mergedConfig.getContextInitializerClasses());
assertEquals(expectedInitializerClasses, mergedConfig.getContextInitializerClasses());
}
/**
* Introduced to investigate claims made in a discussion on
* <a href="https://stackoverflow.com/questions/24725438/what-could-cause-a-class-implementing-applicationlistenercontextrefreshedevent">Stack Overflow</a>.
*/
@Test
public void buildMergedConfigWithAtWebAppConfigurationWithAnnotationAndClassesOnSuperclass() {
Class<?> webTestClass = WebClassesFoo.class;
Class<?> standardTestClass = ClassesFoo.class;
WebMergedContextConfiguration webMergedConfig = (WebMergedContextConfiguration) buildMergedContextConfiguration(webTestClass);
MergedContextConfiguration standardMergedConfig = buildMergedContextConfiguration(standardTestClass);
assertEquals(webMergedConfig, webMergedConfig);
assertEquals(standardMergedConfig, standardMergedConfig);
assertNotEquals(standardMergedConfig, webMergedConfig);
assertNotEquals(webMergedConfig, standardMergedConfig);
assertMergedConfig(webMergedConfig, webTestClass, EMPTY_STRING_ARRAY, array(FooConfig.class),
WebDelegatingSmartContextLoader.class);
assertMergedConfig(standardMergedConfig, standardTestClass, EMPTY_STRING_ARRAY,
array(FooConfig.class), DelegatingSmartContextLoader.class);
}
@Override
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
if (context instanceof WebApplicationContext) {
WebApplicationContext wac = (WebApplicationContext) context;
ServletContext sc = wac.getServletContext();
if (sc != null) {
sc.setAttribute("javax.websocket.server.ServerContainer", new MockServerContainer());
}
}
}
/**
* Ensure that the supplied {@link MergedContextConfiguration} does not
* contain {@link MergedContextConfiguration#getClasses() classes}.
* @since 4.0.4
* @see AbstractGenericContextLoader#validateMergedContextConfiguration
*/
@Override
protected void validateMergedContextConfiguration(MergedContextConfiguration mergedConfig) {
if (mergedConfig.hasClasses()) {
String msg = String.format(
"Test class [%s] has been configured with @ContextConfiguration's 'classes' attribute %s, "
+ "but %s does not support annotated classes.", mergedConfig.getTestClass().getName(),
ObjectUtils.nullSafeToString(mergedConfig.getClasses()), getClass().getSimpleName());
logger.error(msg);
throw new IllegalStateException(msg);
}
}
/**
* @since 4.0.4
*/
@Test
public void configMustNotContainLocations() throws Exception {
expectedException.expect(IllegalStateException.class);
expectedException.expectMessage(containsString("does not support resource locations"));
MergedContextConfiguration mergedConfig = new MergedContextConfiguration(getClass(),
new String[] { "config.xml" }, EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, contextLoader);
contextLoader.loadContext(mergedConfig);
}
/**
* Ensure that the supplied {@link MergedContextConfiguration} does not
* contain {@link MergedContextConfiguration#getClasses() classes}.
* @since 4.0.4
* @see AbstractGenericContextLoader#validateMergedContextConfiguration
*/
@Override
protected void validateMergedContextConfiguration(MergedContextConfiguration mergedConfig) {
if (mergedConfig.hasClasses()) {
String msg = String.format(
"Test class [%s] has been configured with @ContextConfiguration's 'classes' attribute %s, "
+ "but %s does not support annotated classes.", mergedConfig.getTestClass().getName(),
ObjectUtils.nullSafeToString(mergedConfig.getClasses()), getClass().getSimpleName());
logger.error(msg);
throw new IllegalStateException(msg);
}
}
/**
* Construct a new {@code DefaultTestContext} from the supplied arguments.
* @param testClass the test class for this test context
* @param mergedContextConfiguration the merged application context
* configuration for this test context
* @param cacheAwareContextLoaderDelegate the delegate to use for loading
* and closing the application context for this test context
*/
public DefaultTestContext(Class<?> testClass, MergedContextConfiguration mergedContextConfiguration,
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate) {
Assert.notNull(testClass, "Test Class must not be null");
Assert.notNull(mergedContextConfiguration, "MergedContextConfiguration must not be null");
Assert.notNull(cacheAwareContextLoaderDelegate, "CacheAwareContextLoaderDelegate must not be null");
this.testClass = testClass;
this.mergedContextConfiguration = mergedContextConfiguration;
this.cacheAwareContextLoaderDelegate = cacheAwareContextLoaderDelegate;
}
/**
* Delegates to an appropriate candidate {@code SmartContextLoader} to load
* an {@link ApplicationContext}.
* <p>Delegation is based on explicit knowledge of the implementations of the
* default loaders for {@linkplain #getXmlLoader() XML configuration files and
* Groovy scripts} and {@linkplain #getAnnotationConfigLoader() annotated classes}.
* Specifically, the delegation algorithm is as follows:
* <ul>
* <li>If the resource locations in the supplied {@code MergedContextConfiguration}
* are not empty and the annotated classes are empty,
* the XML-based loader will load the {@code ApplicationContext}.</li>
* <li>If the annotated classes in the supplied {@code MergedContextConfiguration}
* are not empty and the resource locations are empty,
* the annotation-based loader will load the {@code ApplicationContext}.</li>
* </ul>
* @param mergedConfig the merged context configuration to use to load the application context
* @throws IllegalArgumentException if the supplied merged configuration is {@code null}
* @throws IllegalStateException if neither candidate loader is capable of loading an
* {@code ApplicationContext} from the supplied merged context configuration
*/
@Override
public ApplicationContext loadContext(MergedContextConfiguration mergedConfig) throws Exception {
Assert.notNull(mergedConfig, "MergedContextConfiguration must not be null");
Assert.state(!(mergedConfig.hasLocations() && mergedConfig.hasClasses()), () -> String.format(
"Neither %s nor %s supports loading an ApplicationContext from %s: " +
"declare either 'locations' or 'classes' but not both.", name(getXmlLoader()),
name(getAnnotationConfigLoader()), mergedConfig));
SmartContextLoader[] candidates = {getXmlLoader(), getAnnotationConfigLoader()};
for (SmartContextLoader loader : candidates) {
// Determine if each loader can load a context from the mergedConfig. If it
// can, let it; otherwise, keep iterating.
if (supports(loader, mergedConfig)) {
return delegateLoading(loader, mergedConfig);
}
}
// If neither of the candidates supports the mergedConfig based on resources but
// ACIs or customizers were declared, then delegate to the annotation config
// loader.
if (!mergedConfig.getContextInitializerClasses().isEmpty() || !mergedConfig.getContextCustomizers().isEmpty()) {
return delegateLoading(getAnnotationConfigLoader(), mergedConfig);
}
// else...
throw new IllegalStateException(String.format(
"Neither %s nor %s was able to load an ApplicationContext from %s.",
name(getXmlLoader()), name(getAnnotationConfigLoader()), mergedConfig));
}
private static ApplicationContext delegateLoading(SmartContextLoader loader, MergedContextConfiguration mergedConfig)
throws Exception {
if (logger.isDebugEnabled()) {
logger.debug(String.format("Delegating to %s to load context from %s.", name(loader), mergedConfig));
}
return loader.loadContext(mergedConfig);
}
@Test
public void configMustNotContainAnnotatedClasses() throws Exception {
expectedException.expect(IllegalStateException.class);
expectedException.expectMessage(containsString("does not support annotated classes"));
GenericPropertiesContextLoader loader = new GenericPropertiesContextLoader();
MergedContextConfiguration mergedConfig = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY,
new Class<?>[] { getClass() }, EMPTY_STRING_ARRAY, loader);
loader.loadContext(mergedConfig);
}
@Test
public void loadContextWithXmlConfig() throws Exception {
MergedContextConfiguration mergedConfig = new MergedContextConfiguration(
XmlTestCase.class,
new String[] { "classpath:/org/springframework/test/context/support/DelegatingSmartContextLoaderTests$XmlTestCase-context.xml" },
EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader);
assertApplicationContextLoadsAndContainsFooString(mergedConfig);
}
/**
* Delegates to an appropriate candidate {@code SmartContextLoader} to load
* an {@link ApplicationContext}.
* <p>Delegation is based on explicit knowledge of the implementations of the
* default loaders for {@linkplain #getXmlLoader() XML configuration files and
* Groovy scripts} and {@linkplain #getAnnotationConfigLoader() annotated classes}.
* Specifically, the delegation algorithm is as follows:
* <ul>
* <li>If the resource locations in the supplied {@code MergedContextConfiguration}
* are not empty and the annotated classes are empty,
* the XML-based loader will load the {@code ApplicationContext}.</li>
* <li>If the annotated classes in the supplied {@code MergedContextConfiguration}
* are not empty and the resource locations are empty,
* the annotation-based loader will load the {@code ApplicationContext}.</li>
* </ul>
* @param mergedConfig the merged context configuration to use to load the application context
* @throws IllegalArgumentException if the supplied merged configuration is {@code null}
* @throws IllegalStateException if neither candidate loader is capable of loading an
* {@code ApplicationContext} from the supplied merged context configuration
*/
@Override
public ApplicationContext loadContext(MergedContextConfiguration mergedConfig) throws Exception {
Assert.notNull(mergedConfig, "MergedContextConfiguration must not be null");
Assert.state(!(mergedConfig.hasLocations() && mergedConfig.hasClasses()), () -> String.format(
"Neither %s nor %s supports loading an ApplicationContext from %s: " +
"declare either 'locations' or 'classes' but not both.", name(getXmlLoader()),
name(getAnnotationConfigLoader()), mergedConfig));
SmartContextLoader[] candidates = {getXmlLoader(), getAnnotationConfigLoader()};
for (SmartContextLoader loader : candidates) {
// Determine if each loader can load a context from the mergedConfig. If it
// can, let it; otherwise, keep iterating.
if (supports(loader, mergedConfig)) {
return delegateLoading(loader, mergedConfig);
}
}
// If neither of the candidates supports the mergedConfig based on resources but
// ACIs or customizers were declared, then delegate to the annotation config
// loader.
if (!mergedConfig.getContextInitializerClasses().isEmpty() || !mergedConfig.getContextCustomizers().isEmpty()) {
return delegateLoading(getAnnotationConfigLoader(), mergedConfig);
}
// else...
throw new IllegalStateException(String.format(
"Neither %s nor %s was able to load an ApplicationContext from %s.",
name(getXmlLoader()), name(getAnnotationConfigLoader()), mergedConfig));
}
/**
* @since 4.1
*/
@Test
public void loadContextWithLocationsAndConfigurationClasses() throws Exception {
expectedException.expect(IllegalStateException.class);
expectedException.expectMessage(startsWith("Neither"));
expectedException.expectMessage(endsWith("declare either 'locations' or 'classes' but not both."));
MergedContextConfiguration mergedConfig = new MergedContextConfiguration(getClass(),
new String[] {"test.xml"}, new Class<?>[] {getClass()}, EMPTY_STRING_ARRAY, loader);
loader.loadContext(mergedConfig);
}
@Override
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
context.addBeanFactoryPostProcessor(new EnvironmentPostProcessor(context.getEnvironment()));
BeanDefinitionRegistry registry = getBeanDefinitionRegistry(context);
RootBeanDefinition registrarDefinition = new RootBeanDefinition();
registrarDefinition.setBeanClass(PreloadableEmbeddedPostgresRegistrar.class);
registrarDefinition.getConstructorArgumentValues()
.addIndexedArgumentValue(0, databaseAnnotations);
registry.registerBeanDefinition("preloadableEmbeddedPostgresRegistrar", registrarDefinition);
}
/**
* Ensure that the supplied {@link MergedContextConfiguration} does not
* contain {@link MergedContextConfiguration#getClasses() classes}.
* @since 4.0.4
* @see AbstractGenericContextLoader#validateMergedContextConfiguration
*/
@Override
protected void validateMergedContextConfiguration(MergedContextConfiguration mergedConfig) {
if (mergedConfig.hasClasses()) {
String msg = String.format(
"Test class [%s] has been configured with @ContextConfiguration's 'classes' attribute %s, "
+ "but %s does not support annotated classes.", mergedConfig.getTestClass().getName(),
ObjectUtils.nullSafeToString(mergedConfig.getClasses()), getClass().getSimpleName());
logger.error(msg);
throw new IllegalStateException(msg);
}
}
@Test
public void buildMergedConfigWithOverriddenInitializersAndClasses() {
Class<?> testClass = OverriddenInitializersAndClassesBar.class;
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass);
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, classes(BarConfig.class),
initializers(BarInitializer.class), DelegatingSmartContextLoader.class);
}
@Test
public void buildMergedConfigWithLocalAndInheritedAnnotationsAndClasses() {
Class<?> testClass = ClassesBar.class;
Class<?>[] expectedClasses = new Class<?>[] { FooConfig.class, BarConfig.class };
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass);
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses,
AnnotationConfigContextLoader.class);
}
@Override
public ApplicationContext loadContext(MergedContextConfiguration mergedContextConfiguration) {
synchronized (this.contextCache) {
ApplicationContext context = this.contextCache.get(mergedContextConfiguration);
if (context == null) {
try {
context = loadContextInternal(mergedContextConfiguration);
if (logger.isDebugEnabled()) {
logger.debug(String.format("Storing ApplicationContext [%s] in cache under key [%s]",
System.identityHashCode(context), mergedContextConfiguration));
}
this.contextCache.put(mergedContextConfiguration, context);
}
catch (Exception ex) {
throw new IllegalStateException("Failed to load ApplicationContext", ex);
}
}
else {
if (logger.isDebugEnabled()) {
logger.debug(String.format("Retrieved ApplicationContext [%s] from cache with key [%s]",
System.identityHashCode(context), mergedContextConfiguration));
}
}
this.contextCache.logStatistics();
return context;
}
}
private void assertApplicationContextLoadsAndContainsFooString(MergedContextConfiguration mergedConfig)
throws Exception {
ApplicationContext applicationContext = loader.loadContext(mergedConfig);
assertNotNull(applicationContext);
assertEquals("foo", applicationContext.getBean(String.class));
assertTrue(applicationContext instanceof ConfigurableApplicationContext);
((ConfigurableApplicationContext) applicationContext).close();
}
@Test
public void buildMergedConfigWithLocalAndInheritedAnnotationsAndLocations() {
Class<?> testClass = LocationsBar.class;
String[] expectedLocations = array("/foo.xml", "/bar.xml");
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass);
assertMergedConfig(mergedConfig, testClass, expectedLocations, EMPTY_CLASS_ARRAY,
AnnotationConfigContextLoader.class);
}
@Test
public void buildMergedConfigWithLocalInitializer() {
Class<?> testClass = InitializersFoo.class;
Class<?>[] expectedClasses = new Class<?>[] { FooConfig.class };
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> expectedInitializerClasses//
= new HashSet<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>>();
expectedInitializerClasses.add(FooInitializer.class);
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass);
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses, expectedInitializerClasses,
DelegatingSmartContextLoader.class);
}
MergedContextConfiguration buildMergedContextConfiguration(Class<?> testClass) {
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate = Mockito.mock(CacheAwareContextLoaderDelegate.class);
BootstrapContext bootstrapContext = BootstrapTestUtils.buildBootstrapContext(testClass, cacheAwareContextLoaderDelegate);
TestContextBootstrapper bootstrapper = BootstrapTestUtils.resolveTestContextBootstrapper(bootstrapContext);
return bootstrapper.buildMergedContextConfiguration();
}
@Test
public void buildImplicitMergedConfigWithoutAnnotation() {
Class<?> testClass = Enigma.class;
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass);
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, DelegatingSmartContextLoader.class);
}
@Test
public void buildMergedConfigWithMetaAnnotationAndLocations() {
Class<?> testClass = MetaLocationsFoo.class;
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass);
assertMergedConfig(mergedConfig, testClass, array("classpath:/foo.xml"), EMPTY_CLASS_ARRAY,
DelegatingSmartContextLoader.class);
}
@Test
public void buildMergedConfigWithLocalAnnotationAndClasses() {
Class<?> testClass = ClassesFoo.class;
MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass);
assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, array(FooConfig.class),
DelegatingSmartContextLoader.class);
}