@Override public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { Class<?> testClass = mergedConfig.getTestClass(); FlywayTest flywayAnnotation = AnnotatedElementUtils.findMergedAnnotation(testClass, FlywayTest.class); BeanDefinitionRegistry registry = getBeanDefinitionRegistry(context); RootBeanDefinition registrarDefinition = new RootBeanDefinition(); registrarDefinition.setBeanClass(PreloadableEmbeddedPostgresRegistrar.class); registrarDefinition.getConstructorArgumentValues() .addIndexedArgumentValue(0, databaseAnnotation); registrarDefinition.getConstructorArgumentValues() .addIndexedArgumentValue(1, flywayAnnotation); registry.registerBeanDefinition("preloadableEmbeddedPostgresRegistrar", registrarDefinition); }
@Override public ApplicationContext loadContext(final MergedContextConfiguration config) throws Exception { assertValidAnnotations(config.getTestClass()); SpringApplication application = getSpringApplication(); application.setMainApplicationClass(config.getTestClass()); application.setSources(getSources(config)); ConfigurableEnvironment environment = new StandardEnvironment(); if (!ObjectUtils.isEmpty(config.getActiveProfiles())) { setActiveProfiles(environment, config.getActiveProfiles()); } Map<String, Object> properties = getEnvironmentProperties(config); addProperties(environment, properties); application.setEnvironment(environment); List<ApplicationContextInitializer<?>> initializers = getInitializers(config, application); if (config instanceof WebMergedContextConfiguration) { new WebConfigurer().configure(config, application, initializers); } else { application.setWebEnvironment(false); } application.setInitializers(initializers); ConfigurableApplicationContext applicationContext = application.run(); return applicationContext; }
/** * {@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.get(parent); if (list == null) { list = new HashSet<MergedContextConfiguration>(); this.hierarchyMap.put(parent, list); } 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); }
/** * 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; }
void assertMergedConfig( MergedContextConfiguration mergedConfig, Class<?> expectedTestClass, String[] expectedLocations, Class<?>[] expectedClasses, Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> 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()); }
@Override public ApplicationContext loadContext(MergedContextConfiguration mergedConfig) throws Exception { Class<?> testClass = getTestClass(); if (logger.isDebugEnabled()) { logger.debug("Loading ApplicationContext for merged context configuration [{}].", mergedConfig); } // Pre CamelContext(s) instantiation setup CamelAnnotationsHandler.handleDisableJmx(null, testClass); try { SpringCamelContext.setNoStart(true); System.setProperty("skipStartingCamelContext", "true"); ConfigurableApplicationContext context = (ConfigurableApplicationContext) super.loadContext(mergedConfig); SpringCamelContext.setNoStart(false); System.clearProperty("skipStartingCamelContext"); return loadContext(context, testClass); } finally { cleanup(testClass); } }
@Override public ApplicationContext loadContext(MergedContextConfiguration config) throws Exception { SpringApplication application = new SpringApplication(); application.setMainApplicationClass(config.getTestClass()); application.setWebEnvironment(false); application.setSources( new LinkedHashSet<Object>(Arrays.asList(config.getClasses()))); ConfigurableEnvironment environment = new StandardEnvironment(); Map<String, Object> properties = new LinkedHashMap<String, Object>(); properties.put("spring.jmx.enabled", "false"); properties.putAll(TestPropertySourceUtils .convertInlinedPropertiesToMap(config.getPropertySourceProperties())); environment.getPropertySources().addAfter( StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, new MapPropertySource("integrationTest", properties)); application.setEnvironment(environment); return application.run(); }
protected Class<?>[] getOrFindConfigurationClasses( MergedContextConfiguration mergedConfig) { Class<?>[] classes = mergedConfig.getClasses(); if (containsNonTestComponent(classes) || mergedConfig.hasLocations() || !mergedConfig.getContextInitializerClasses().isEmpty()) { return classes; } Class<?> found = new SpringBootConfigurationFinder() .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); }
/** * Modeled after the Spring implementation in {@link AbstractGenericContextLoader}, * this method creates and refreshes the application context while providing for * processing of additional Camel specific post-refresh actions. We do not provide the * pre-post hooks for customization seen in {@link AbstractGenericContextLoader} because * they probably are unnecessary for 90+% of users. * <p/> * For some functionality, we cannot use {@link org.springframework.test.context.TestExecutionListener} because we need * to both produce the desired outcome during application context loading, and also cleanup * after ourselves even if the test class never executes. Thus the listeners, which * only run if the application context is successfully initialized are insufficient to * provide the behavior described above. */ @Override public ApplicationContext loadContext(MergedContextConfiguration mergedConfig) throws Exception { Class<?> testClass = getTestClass(); if (LOG.isDebugEnabled()) { LOG.debug("Loading ApplicationContext for merged context configuration [{}].", mergedConfig); } try { GenericApplicationContext context = createContext(testClass, mergedConfig); context.getEnvironment().setActiveProfiles(mergedConfig.getActiveProfiles()); loadBeanDefinitions(context, mergedConfig); return loadContext(context, testClass); } finally { cleanup(testClass); } }
/** * <p>Will register mock factory and all additional beans required by springmock.</p> * <p> * <p>It is possible to register and inject more beans passing additionalDefinitions to the constructor</p> * * @param configurableApplicationContext * @param mergedContextConfiguration */ public final void customizeContext(ConfigurableApplicationContext configurableApplicationContext, MergedContextConfiguration mergedContextConfiguration) { final BeanDefinitionRegistry registry = (BeanDefinitionRegistry) configurableApplicationContext; registerDoubleRegistry(registry); registerDoubleFactory(configurableApplicationContext.getBeanFactory(), registry); registerMockClassResolver(registry); registerDoubleDefinitionRegisteringProcessor(registry); registerSpyRegistrationPostProcessor(registry); registerAdditionalBeanDefinitions(registry, additionalDefinitions); }
private Map<String, Object> getEnvironmentProperties(Class<?> testClass) throws Exception { TestContext context = new ExposedTestContextManager(testClass) .getExposedTestContext(); MergedContextConfiguration config = (MergedContextConfiguration) ReflectionTestUtils .getField(context, "mergedContextConfiguration"); return TestPropertySourceUtils .convertInlinedPropertiesToMap(config.getPropertySourceProperties()); }
/** * 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 = AnnotationUtils.findAnnotation(mergedConfig.getTestClass(), WebAppConfiguration.class); if (webAppConfiguration != null) { return new WebMergedContextConfiguration(mergedConfig, webAppConfiguration.value()); } // else... return mergedConfig; }
@Override public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedContextConfiguration) { if (context instanceof BeanDefinitionRegistry) { MockitoPostProcessor.register((BeanDefinitionRegistry) context, this.definitions); } }
/** * 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; never {@code null} * @param mergedContextConfiguration the merged application context * configuration for this test context; never {@code null} * @param cacheAwareContextLoaderDelegate the delegate to use for loading * and closing the application context for this test context; never {@code null} */ public DefaultTestContext(Class<?> testClass, MergedContextConfiguration mergedContextConfiguration, CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate) { Assert.notNull(testClass, "testClass 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; }
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); }
private boolean supports(SmartContextLoader loader, MergedContextConfiguration mergedConfig) { if (loader == getAnnotationConfigLoader()) { return mergedConfig.hasClasses() && !mergedConfig.hasLocations(); } else { return mergedConfig.hasLocations() && !mergedConfig.hasClasses(); } }
@Override public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedContextConfiguration) { if (!this.filterClasses.isEmpty()) { context.getBeanFactory().registerSingleton(EXCLUDE_FILTER_BEAN_NAME, createDelegatingTypeExcludeFilter()); } }
private Set<Object> getSources(MergedContextConfiguration mergedConfig) { Set<Object> sources = new LinkedHashSet<Object>(); sources.addAll(Arrays.asList(mergedConfig.getClasses())); sources.addAll(Arrays.asList(mergedConfig.getLocations())); Assert.state(!sources.isEmpty(), "No configuration classes " + "or locations found in @SpringApplicationConfiguration. " + "For default configuration detection to work you need " + "Spring 4.0.3 or better (found " + SpringVersion.getVersion() + ")."); return sources; }
/** * 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); } }
@Override public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedContextConfiguration) { if (!this.propertySource.isEmpty()) { context.getEnvironment().getPropertySources().addFirst(this.propertySource); } context.getBeanFactory().registerSingleton( PropertyMappingCheckBeanPostProcessor.class.getName(), new PropertyMappingCheckBeanPostProcessor()); }
/** * {@inheritDoc} */ @Override public ApplicationContext get(MergedContextConfiguration key) { Assert.notNull(key, "Key must not be null"); ApplicationContext context = this.contextMap.get(key); if (context == null) { this.missCount.incrementAndGet(); } else { this.hitCount.incrementAndGet(); } return context; }
@Test public void configMustNotContainAnnotatedClasses() throws Exception { expectedException.expect(IllegalStateException.class); expectedException.expectMessage(containsString("does not support annotated classes")); GenericXmlContextLoader loader = new GenericXmlContextLoader(); MergedContextConfiguration mergedConfig = new MergedContextConfiguration(getClass(), EMPTY_STRING_ARRAY, new Class<?>[] { getClass() }, EMPTY_STRING_ARRAY, loader); loader.loadContext(mergedConfig); }
private List<ApplicationContextInitializer<?>> getInitializers( MergedContextConfiguration mergedConfig, SpringApplication application) { List<ApplicationContextInitializer<?>> initializers = new ArrayList<ApplicationContextInitializer<?>>(); initializers.add(new PropertySourceLocationsInitializer( mergedConfig.getPropertySourceLocations())); initializers.addAll(application.getInitializers()); for (Class<? extends ApplicationContextInitializer<?>> initializerClass : mergedConfig .getContextInitializerClasses()) { initializers.add(BeanUtils.instantiate(initializerClass)); } return initializers; }
void assertMergedConfig(MergedContextConfiguration mergedConfig, Class<?> expectedTestClass, String[] expectedLocations, Class<?>[] expectedClasses, Class<? extends ContextLoader> expectedContextLoaderClass) { assertMergedConfig(mergedConfig, expectedTestClass, expectedLocations, expectedClasses, EMPTY_INITIALIZER_CLASSES, expectedContextLoaderClass); }
@Test public void buildMergedConfigWithoutAnnotation() { Class<?> testClass = Enigma.class; MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass); assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, null); }
protected Map<String, Object> getEnvironmentProperties( MergedContextConfiguration config) { Map<String, Object> properties = new LinkedHashMap<String, Object>(); // JMX bean names will clash if the same bean is used in multiple contexts disableJmx(properties); properties.putAll(TestPropertySourceUtils .convertInlinedPropertiesToMap(config.getPropertySourceProperties())); if (!TestAnnotations.isIntegrationTest(config)) { properties.putAll(getDefaultEnvironmentProperties()); } return properties; }
void configure(MergedContextConfiguration configuration, SpringApplication application, List<ApplicationContextInitializer<?>> initializers) { WebMergedContextConfiguration webConfiguration = (WebMergedContextConfiguration) configuration; addMockServletContext(initializers, webConfiguration); application.setApplicationContextClass(WEB_CONTEXT_CLASS); }
@Test public void buildMergedConfigWithMetaAnnotationAndLocations() { Class<?> testClass = MetaLocationsFoo.class; MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass); assertMergedConfig(mergedConfig, testClass, new String[] { "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, new Class<?>[] { FooConfig.class }, DelegatingSmartContextLoader.class); }
private Map<String, Object> getEnvironmentProperties(Class<?> testClass) throws Exception { TestContext context = new ExposedTestContextManager(testClass) .getExposedTestContext(); new IntegrationTestPropertiesListener().prepareTestInstance(context); MergedContextConfiguration config = (MergedContextConfiguration) ReflectionTestUtils .getField(context, "mergedContextConfiguration"); return TestPropertySourceUtils .convertInlinedPropertiesToMap(config.getPropertySourceProperties()); }
@Test public void buildMergedConfigWithLocalAnnotationAndOverriddenContextLoaderAndLocations() { Class<?> testClass = PropertiesLocationsFoo.class; Class<? extends ContextLoader> expectedContextLoaderClass = GenericPropertiesContextLoader.class; MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass); assertMergedConfig(mergedConfig, testClass, new String[] { "classpath:/foo.properties" }, EMPTY_CLASS_ARRAY, expectedContextLoaderClass); }
@Test public void buildMergedConfigWithLocalAnnotationAndOverriddenContextLoaderAndClasses() { Class<?> testClass = PropertiesClassesFoo.class; Class<? extends ContextLoader> expectedContextLoaderClass = GenericPropertiesContextLoader.class; MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass); assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, new Class<?>[] { FooConfig.class }, expectedContextLoaderClass); }
@Test public void buildMergedConfigWithLocalAndInheritedAnnotationsAndLocations() { Class<?> testClass = LocationsBar.class; String[] expectedLocations = new String[] { "/foo.xml", "/bar.xml" }; MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass); assertMergedConfig(mergedConfig, testClass, expectedLocations, EMPTY_CLASS_ARRAY, AnnotationConfigContextLoader.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); }
@Test public void buildMergedConfigWithAnnotationsAndOverriddenLocations() { Class<?> testClass = OverriddenLocationsBar.class; String[] expectedLocations = new String[] { "/bar.xml" }; MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass); assertMergedConfig(mergedConfig, testClass, expectedLocations, EMPTY_CLASS_ARRAY, AnnotationConfigContextLoader.class); }
@Test public void buildMergedConfigWithAnnotationsAndOverriddenClasses() { Class<?> testClass = OverriddenClassesBar.class; Class<?>[] expectedClasses = new Class<?>[] { BarConfig.class }; MergedContextConfiguration mergedConfig = buildMergedContextConfiguration(testClass); assertMergedConfig(mergedConfig, testClass, EMPTY_STRING_ARRAY, expectedClasses, AnnotationConfigContextLoader.class); }