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()); }
@Test public void equalsWithEmptyArrays() { MergedContextConfiguration mergedConfig1 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); MergedContextConfiguration mergedConfig2 = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, EMPTY_STRING_ARRAY, loader); assertEquals(mergedConfig1, mergedConfig2); }
/** * {@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(); } }
/** * 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); } }
/** * Ensure that the supplied {@link MergedContextConfiguration} does not * contain {@link MergedContextConfiguration#getLocations() locations}. * @since 4.0.4 * @see AbstractGenericContextLoader#validateMergedContextConfiguration */ @Override protected void validateMergedContextConfiguration(MergedContextConfiguration mergedConfig) { if (mergedConfig.hasLocations()) { String msg = String.format("Test class [%s] has been configured with @ContextConfiguration's 'locations' " + "(or 'value') attribute %s, but %s does not support resource locations.", mergedConfig.getTestClass().getName(), ObjectUtils.nullSafeToString(mergedConfig.getLocations()), getClass().getSimpleName()); logger.error(msg); throw new IllegalStateException(msg); } }
/** * Load the {@code ApplicationContext} for the supplied merged context configuration. * <p>Supports both the {@link SmartContextLoader} and {@link ContextLoader} SPIs. * @throws Exception if an error occurs while loading the application context */ protected ApplicationContext loadContextInternal(MergedContextConfiguration mergedContextConfiguration) throws Exception { ContextLoader contextLoader = mergedContextConfiguration.getContextLoader(); Assert.notNull(contextLoader, "Cannot load an ApplicationContext with a NULL 'contextLoader'. " + "Consider annotating your test class with @ContextConfiguration or @ContextHierarchy."); ApplicationContext applicationContext; if (contextLoader instanceof SmartContextLoader) { SmartContextLoader smartContextLoader = (SmartContextLoader) contextLoader; applicationContext = smartContextLoader.loadContext(mergedContextConfiguration); } else { String[] locations = mergedContextConfiguration.getLocations(); Assert.notNull(locations, "Cannot load an ApplicationContext with a NULL 'locations' array. " + "Consider annotating your test class with @ContextConfiguration or @ContextHierarchy."); applicationContext = contextLoader.loadContext(locations); } return applicationContext; }
/** * Create a new {@link MergedContextConfiguration} with different classes and * properties. * @param mergedConfig the source config * @param classes the replacement classes * @param propertySourceProperties the replacement properties * @return a new {@link MergedContextConfiguration} */ protected final MergedContextConfiguration createModifiedConfig( MergedContextConfiguration mergedConfig, Class<?>[] classes, String[] propertySourceProperties) { return new MergedContextConfiguration(mergedConfig.getTestClass(), mergedConfig.getLocations(), classes, mergedConfig.getContextInitializerClasses(), mergedConfig.getActiveProfiles(), mergedConfig.getPropertySourceLocations(), propertySourceProperties, mergedConfig.getContextCustomizers(), mergedConfig.getContextLoader(), getCacheAwareContextLoaderDelegate(), mergedConfig.getParent()); }
public TinyMergedContextConfiguration(ContextLoader contextLoader, CacheAwareContextLoaderDelegate contextLoaderDelegate, MergedContextConfiguration mergedContextConfiguration, MergedContextConfiguration parentConfiguration) { super(mergedContextConfiguration.getTestClass(), mergedContextConfiguration.getLocations(), mergedContextConfiguration.getClasses(), mergedContextConfiguration.getActiveProfiles(), contextLoader); this.mergedContextConfiguration = mergedContextConfiguration; this.contextLoaderDelegate = contextLoaderDelegate; this.parentConfiguration = parentConfiguration; }
public final ConfigurableApplicationContext loadContext(MergedContextConfiguration mergedConfig) throws Exception { if (log.isDebugEnabled()) { log.debug("Loading ApplicationContext for merged context configuration [" + mergedConfig + "]."); } ResourceLoadingXmlApplicationContext context = new ResourceLoadingXmlApplicationContext(mergedConfig.getLocations(), testResourceLoader, false); context.getEnvironment().setActiveProfiles(mergedConfig.getActiveProfiles()); prepareContext(context); context.refresh(); context.registerShutdownHook(); return context; }
/** * Determine if this {@code MergedContextConfiguration} instance has * path-based context resource locations. * @return {@code true} if the {@link #getLocations() locations} array is not empty * @since 4.0.4 * @see #hasResources() * @see #hasClasses() */ public boolean hasLocations() { return !ObjectUtils.isEmpty(getLocations()); }
context.getEnvironment().setActiveProfiles(mergedConfig.getActiveProfiles()); TestPropertySourceUtils.addPropertiesFilesToEnvironment(context, mergedConfig.getPropertySourceLocations()); TestPropertySourceUtils.addInlinedPropertiesToEnvironment(context, mergedConfig.getPropertySourceProperties()); invokeApplicationContextInitializers(context, mergedConfig);
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()), if (!mergedConfig.getContextInitializerClasses().isEmpty() || !mergedConfig.getContextCustomizers().isEmpty()) { return delegateLoading(getAnnotationConfigLoader(), mergedConfig);
/** * Returns a {@link WebMergedContextConfiguration} if the test class in the * supplied {@code MergedContextConfiguration} is annotated with * {@link WebAppConfiguration @WebAppConfiguration} and otherwise returns * the supplied instance unmodified. */ @Override protected MergedContextConfiguration processMergedContextConfiguration(MergedContextConfiguration mergedConfig) { WebAppConfiguration webAppConfiguration = AnnotatedElementUtils.findMergedAnnotation(mergedConfig.getTestClass(), WebAppConfiguration.class); if (webAppConfiguration != null) { return new WebMergedContextConfiguration(mergedConfig, webAppConfiguration.value()); } else { return mergedConfig; } }
@Override protected void loadBeanDefinitions(GenericApplicationContext context, MergedContextConfiguration mergedConfig) { // Order doesn't matter: <bean> always wins over @Bean. new XmlBeanDefinitionReader(context).loadBeanDefinitions(mergedConfig.getLocations()); new AnnotatedBeanDefinitionReader(context).register(mergedConfig.getClasses()); }
protected Class<?>[] getOrFindConfigurationClasses( MergedContextConfiguration mergedConfig) { Class<?>[] classes = mergedConfig.getClasses(); if (containsNonTestComponent(classes) || mergedConfig.hasLocations()) { return classes; } Class<?> found = new AnnotatedClassFinder(SpringBootConfiguration.class) .findFromClass(mergedConfig.getTestClass()); Assert.state(found != null, "Unable to find a @SpringBootConfiguration, you need to use " + "@ContextConfiguration or @SpringBootTest(classes=...) " + "with your test"); logger.info("Found @SpringBootConfiguration " + found.getName() + " for test " + mergedConfig.getTestClass()); return merge(found, classes); }
/** * Return the {@link ApplicationContextInitializer initializers} that will be applied * to the context. By default this method will adapt {@link ContextCustomizer context * customizers}, add {@link SpringApplication#getInitializers() application * initializers} and add * {@link MergedContextConfiguration#getContextInitializerClasses() initializers * specified on the test}. * @param config the source context configuration * @param application the application instance * @return the initializers to apply * @since 2.0.0 */ protected List<ApplicationContextInitializer<?>> getInitializers( MergedContextConfiguration config, SpringApplication application) { List<ApplicationContextInitializer<?>> initializers = new ArrayList<>(); for (ContextCustomizer contextCustomizer : config.getContextCustomizers()) { initializers.add(new ContextCustomizerAdapter(contextCustomizer, config)); } initializers.addAll(application.getInitializers()); for (Class<? extends ApplicationContextInitializer<?>> initializerClass : config .getContextInitializerClasses()) { initializers.add(BeanUtils.instantiateClass(initializerClass)); } if (config.getParent() != null) { initializers.add(new ParentContextApplicationContextInitializer( config.getParentApplicationContext())); } return initializers; }
/** * Determine if this {@code MergedContextConfiguration} instance has * class-based resources. * @return {@code true} if the {@link #getClasses() classes} array is not empty * @since 4.0.4 * @see #hasResources() * @see #hasLocations() */ public boolean hasClasses() { return !ObjectUtils.isEmpty(getClasses()); }
.getContextLoader(); if (contextLoader == null) { contextLoader = BeanUtils.instantiateClass( MergedContextConfiguration newParentMergedContextConfiguration = new MergedContextConfiguration( null, null, null, null, tinyContextLoader); cacheAwareContextLoaderDelegate.getPublicContextCache().put(
private boolean isFromConfiguration(MergedContextConfiguration candidateConfig, ContextConfiguration configuration) { ContextConfigurationAttributes attributes = new ContextConfigurationAttributes( candidateConfig.getTestClass(), configuration); Set<Class<?>> configurationClasses = new HashSet<>( Arrays.asList(attributes.getClasses())); for (Class<?> candidate : candidateConfig.getClasses()) { if (configurationClasses.contains(candidate)) { return true; } } return false; }
ApplicationContext parent = mergedConfig.getParentApplicationContext(); if (parent != null) { context.setParent(parent);