类org.springframework.test.context.MergedContextConfiguration源码实例Demo

下面列出了怎么用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);
	}
}
 
源代码12 项目: spring-analysis-note   文件: DefaultTestContext.java
/**
 * 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);
}
 
 同包方法