/* * Copyright 2010-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.data.gemfire.support; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.CoreMatchers.isA; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; import java.util.Arrays; import java.util.Properties; import org.apache.commons.logging.Log; import org.junit.After; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.Matchers; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextException; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.ApplicationContextEvent; import org.springframework.context.event.ContextClosedEvent; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.ContextStartedEvent; import org.springframework.context.event.ContextStoppedEvent; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.util.ObjectUtils; /** * The SpringContextBootstrappingInitializerTest class is a test suite of test cases testing the contract * and functionality of the SpringContextBootstrappingInitializer class. This test class focuses on testing isolated * units of functionality in the Initializer class directly, mocking any dependencies as appropriate, in order for the * class to uphold it's contract. * * @author John Blum * @see org.junit.Test * @see org.mockito.Mockito * @see org.springframework.context.ApplicationContext * @see org.springframework.context.ConfigurableApplicationContext * @see org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer * @see org.springframework.data.gemfire.support.SpringContextBootstrappingInitializerIntegrationTest * @since 1.4.0 */ @SuppressWarnings("unused") public class SpringContextBootstrappingInitializerTest { @Rule public ExpectedException expectedException = ExpectedException.none(); @After public void tearDown() { SpringContextBootstrappingInitializer.applicationContext = null; SpringContextBootstrappingInitializer.contextRefreshedEvent = null; SpringContextBootstrappingInitializer.setBeanClassLoader(null); SpringContextBootstrappingInitializer.unregister(TestAppConfigOne.class); SpringContextBootstrappingInitializer.unregister(TestAppConfigTwo.class); } protected static Properties createParameters(final String parameter, final String value) { Properties parameters = new Properties(); parameters.setProperty(parameter, value); return parameters; } protected static Properties createParameters(final Properties parameters, final String parameter, final String value) { parameters.setProperty(parameter, value); return parameters; } @Test public void getInitializedApplicationContext() { ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class, "testGetApplicationContext"); SpringContextBootstrappingInitializer.applicationContext = mockApplicationContext; assertThat(SpringContextBootstrappingInitializer.getApplicationContext(), is(sameInstance(mockApplicationContext))); } @Test public void getUninitializedApplicationContext() { expectedException.expect(IllegalStateException.class); expectedException.expectMessage("A Spring ApplicationContext was not configured and initialized properly"); expectedException.expectCause(is(nullValue(Throwable.class))); SpringContextBootstrappingInitializer.getApplicationContext(); } @Test public void setBeanClassLoaderWithCurrentThreadContextClassLoader() { assertThat(SpringContextBootstrappingInitializer.applicationContext, is(nullValue())); SpringContextBootstrappingInitializer.setBeanClassLoader(Thread.currentThread().getContextClassLoader()); } @Test public void setBeanClassLoaderWithCurrentThreadContextClassLoaderWhenApplicationContextIsInactive() { ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class, "MockApplicationContext"); when(mockApplicationContext.isActive()).thenReturn(false); SpringContextBootstrappingInitializer.applicationContext = mockApplicationContext; SpringContextBootstrappingInitializer.setBeanClassLoader(Thread.currentThread().getContextClassLoader()); verify(mockApplicationContext, times(1)).isActive(); } @Test public void setBeanClassLoaderWithCurrentThreadContextClassLoaderWhenApplicationContextIsActive() { ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class, "MockApplicationContext"); when(mockApplicationContext.isActive()).thenReturn(true); expectedException.expect(IllegalStateException.class); expectedException.expectCause(is(nullValue(Throwable.class))); expectedException.expectMessage("A Spring ApplicationContext has already been initialized"); try { SpringContextBootstrappingInitializer.applicationContext = mockApplicationContext; SpringContextBootstrappingInitializer.setBeanClassLoader(Thread.currentThread().getContextClassLoader()); } finally { verify(mockApplicationContext, times(1)).isActive(); } } @Test public void createApplicationContextWhenAnnotatedClassesBasePackagesAndConfigLocationsAreUnspecified() { expectedException.expect(IllegalArgumentException.class); expectedException.expectCause(is(nullValue(Throwable.class))); expectedException.expectMessage("'AnnotatedClasses', 'basePackages' or 'configLocations' must be specified" + " in order to construct and configure an instance of the ConfigurableApplicationContext"); new SpringContextBootstrappingInitializer().createApplicationContext(null, null); } @Test public void createAnnotationApplicationContextWithAnnotatedClasses() { final AnnotationConfigApplicationContext mockAnnotationApplicationContext = mock(AnnotationConfigApplicationContext.class, "MockAnnotationApplicationContext"); final ConfigurableApplicationContext mockXmlApplicationContext = mock(ConfigurableApplicationContext.class, "MockXmlApplicationContext"); Class<?>[] annotatedClasses = { TestAppConfigOne.class, TestAppConfigTwo.class }; SpringContextBootstrappingInitializer.register(annotatedClasses[0]); SpringContextBootstrappingInitializer.register(annotatedClasses[1]); SpringContextBootstrappingInitializer initializer = new SpringContextBootstrappingInitializer() { @Override ConfigurableApplicationContext createApplicationContext(final String[] configLocations) { return (ObjectUtils.isEmpty(configLocations) ? mockAnnotationApplicationContext : mockXmlApplicationContext); } }; ConfigurableApplicationContext actualApplicationContext = initializer.createApplicationContext(null, null); assertThat(actualApplicationContext, is(sameInstance((ConfigurableApplicationContext) mockAnnotationApplicationContext))); verify(mockAnnotationApplicationContext, times(1)).register(annotatedClasses[0], annotatedClasses[1]); } @Test public void createAnnotationApplicationContextWithBasePackages() { final AnnotationConfigApplicationContext mockAnnotationApplicationContext = mock(AnnotationConfigApplicationContext.class, "MockAnnotationApplicationContext"); final ConfigurableApplicationContext mockXmlApplicationContext = mock(ConfigurableApplicationContext.class, "MockXmlApplicationContext"); String[] basePackages = { "org.example.app" }; SpringContextBootstrappingInitializer initializer = new SpringContextBootstrappingInitializer() { @Override ConfigurableApplicationContext createApplicationContext(final String[] configLocations) { return (ObjectUtils.isEmpty(configLocations) ? mockAnnotationApplicationContext : mockXmlApplicationContext); } }; ConfigurableApplicationContext actualApplicationContext = initializer.createApplicationContext(basePackages, null); assertThat(actualApplicationContext, is(sameInstance((ConfigurableApplicationContext) mockAnnotationApplicationContext))); verify(mockAnnotationApplicationContext, times(1)).scan(eq(basePackages[0])); } @Test public void createXmlApplicationContext() { final ConfigurableApplicationContext mockAnnotationApplicationContext = mock(ConfigurableApplicationContext.class, "MockAnnotationApplicationContext"); final ConfigurableApplicationContext mockXmlApplicationContext = mock(ConfigurableApplicationContext.class, "MockXmlApplicationContext"); SpringContextBootstrappingInitializer initializer = new SpringContextBootstrappingInitializer() { @Override ConfigurableApplicationContext createApplicationContext(final String[] configLocations) { return (ObjectUtils.isEmpty(configLocations) ? mockAnnotationApplicationContext : mockXmlApplicationContext); } }; ConfigurableApplicationContext actualApplicationContext = initializer.createApplicationContext(null, new String[] { "/path/to/application/context.xml" }); assertThat(actualApplicationContext, is(sameInstance(mockXmlApplicationContext))); } @Test public void initApplicationContext() { AbstractApplicationContext mockApplicationContext = mock(AbstractApplicationContext.class, "MockApplicationContext"); SpringContextBootstrappingInitializer.setBeanClassLoader(Thread.currentThread().getContextClassLoader()); SpringContextBootstrappingInitializer initializer = new SpringContextBootstrappingInitializer(); assertSame(mockApplicationContext, initializer.initApplicationContext(mockApplicationContext)); verify(mockApplicationContext, times(1)).addApplicationListener(same(initializer)); verify(mockApplicationContext, times(1)).registerShutdownHook(); verify(mockApplicationContext, times(1)).setClassLoader(eq(Thread.currentThread().getContextClassLoader())); } @Test public void initApplicationContextWithNull() { expectedException.expect(IllegalArgumentException.class); expectedException.expectCause(is(nullValue(Throwable.class))); expectedException.expectMessage("ConfigurableApplicationContext must not be null"); new SpringContextBootstrappingInitializer().initApplicationContext(null); } @Test public void refreshApplicationContext() { ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class, "MockApplicationContext"); assertThat(new SpringContextBootstrappingInitializer().refreshApplicationContext(mockApplicationContext), is(sameInstance(mockApplicationContext))); verify(mockApplicationContext, times(1)).refresh(); } @Test public void refreshApplicationContextWithNull() { expectedException.expect(IllegalArgumentException.class); expectedException.expectCause(is(nullValue(Throwable.class))); expectedException.expectMessage("ConfigurableApplicationContext must not be null"); new SpringContextBootstrappingInitializer().refreshApplicationContext(null); } @Test public void registerAnnotatedClasses() { AnnotationConfigApplicationContext mockApplicationContext = mock(AnnotationConfigApplicationContext.class, "MockApplicationContext"); Class<?>[] annotatedClasses = { TestAppConfigOne.class, TestAppConfigTwo.class }; assertThat(new SpringContextBootstrappingInitializer() .registerAnnotatedClasses(mockApplicationContext, annotatedClasses), is(sameInstance(mockApplicationContext))); verify(mockApplicationContext, times(1)).register(annotatedClasses); } @Test public void registerAnnotatedClassesWithEmptyAnnotatedClassesArray() { AnnotationConfigApplicationContext mockApplicationContext = mock(AnnotationConfigApplicationContext.class, "MockApplicationContext"); assertThat(new SpringContextBootstrappingInitializer().registerAnnotatedClasses(mockApplicationContext, new Class<?>[0]), is(sameInstance(mockApplicationContext))); verify(mockApplicationContext, never()).register(any(Class[].class)); } @Test public void registerAnnotatedClassesWithNonAnnotationBasedApplicationContext() { ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class, "MockApplicationContext"); assertThat(new SpringContextBootstrappingInitializer().registerAnnotatedClasses(mockApplicationContext, new Class<?>[] { TestAppConfigOne.class }), is(sameInstance(mockApplicationContext))); } @Test public void scanBasePackages() { AnnotationConfigApplicationContext mockApplicationContext = mock(AnnotationConfigApplicationContext.class, "MockApplicationContext"); String[] basePackages = { "org.example.app", "org.example.plugins" }; assertThat(new SpringContextBootstrappingInitializer().scanBasePackages(mockApplicationContext, basePackages), is(sameInstance(mockApplicationContext))); verify(mockApplicationContext, times(1)).scan(basePackages); } @Test public void scanBasePackagesWithEmptyBasePackagesArray() { AnnotationConfigApplicationContext mockApplicationContext = mock(AnnotationConfigApplicationContext.class, "MockApplicationContext"); assertThat(new SpringContextBootstrappingInitializer().scanBasePackages(mockApplicationContext, null), is(sameInstance(mockApplicationContext))); verify(mockApplicationContext, never()).scan(any(String[].class)); } @Test public void scanBasePackagesWithNonAnnotationBasedApplicationContext() { ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class, "MockApplicationContext"); assertThat(new SpringContextBootstrappingInitializer().scanBasePackages(mockApplicationContext, new String[] { "org.example.app" }), is(sameInstance(mockApplicationContext))); } @Test public void setClassLoader() { AbstractApplicationContext mockApplicationContext = mock(AbstractApplicationContext.class, "MockApplicationContext"); SpringContextBootstrappingInitializer.setBeanClassLoader(Thread.currentThread().getContextClassLoader()); assertThat(new SpringContextBootstrappingInitializer().setClassLoader(mockApplicationContext), is(sameInstance(mockApplicationContext))); verify(mockApplicationContext, times(1)).setClassLoader(eq(Thread.currentThread().getContextClassLoader())); } @Test public void setClassLoaderWithNonSettableClassLoaderApplicationContext() { ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class, "MockApplicationContext"); SpringContextBootstrappingInitializer.setBeanClassLoader(Thread.currentThread().getContextClassLoader()); assertThat(new SpringContextBootstrappingInitializer().setClassLoader(mockApplicationContext), is(sameInstance(mockApplicationContext))); } @Test public void setClassLoaderWithNullClassLoader() { AbstractApplicationContext mockApplicationContext = mock(AbstractApplicationContext.class, "MockApplicationContext"); SpringContextBootstrappingInitializer.setBeanClassLoader(null); assertThat(new SpringContextBootstrappingInitializer().setClassLoader(mockApplicationContext), is(sameInstance(mockApplicationContext))); verify(mockApplicationContext, never()).setClassLoader(any(ClassLoader.class)); } private Class<?>[] annotatedClasses(final Class<?>... annotatedClasses) { return argThat(argument -> { assertThat(argument instanceof Class<?>[], is(true)); return Arrays.equals(annotatedClasses, (Class<?>[]) argument); }); } @Test public void nullSafeGetApplicationContextIdWithNullReference() { assertThat(new SpringContextBootstrappingInitializer().nullSafeGetApplicationContextId(null), is(nullValue())); } @Test public void nullSafeGetApplicationContextIdWithNonNullReference() { ApplicationContext mockApplicationContext = mock(ApplicationContext.class, "MockApplicationContext"); when(mockApplicationContext.getId()).thenReturn("123"); assertThat(new SpringContextBootstrappingInitializer().nullSafeGetApplicationContextId(mockApplicationContext), is(equalTo("123"))); } @Test public void testInitWithAnnotatedClasses() { final AnnotationConfigApplicationContext mockApplicationContext = mock(AnnotationConfigApplicationContext.class, "testInitWithAnnotatedClasses"); doNothing().when(mockApplicationContext).addApplicationListener(any(ApplicationListener.class)); doNothing().when(mockApplicationContext).registerShutdownHook(); doNothing().when(mockApplicationContext).refresh(); doNothing().when(mockApplicationContext).register(Matchers.<Class<?>[]>anyVararg()); //doNothing().when(mockApplicationContext).register(annotatedClasses(TestAppConfigOne.class, TestAppConfigTwo.class)); when(mockApplicationContext.getId()).thenReturn("testInitWithAnnotatedClasses"); when(mockApplicationContext.isRunning()).thenReturn(true); assertNull(SpringContextBootstrappingInitializer.applicationContext); SpringContextBootstrappingInitializer.register(TestAppConfigOne.class); SpringContextBootstrappingInitializer.register(TestAppConfigTwo.class); SpringContextBootstrappingInitializer initializer = new SpringContextBootstrappingInitializer() { @Override protected ConfigurableApplicationContext createApplicationContext(String[] configLocations) { return mockApplicationContext; } }; initializer.init(createParameters("test", "test")); verify(mockApplicationContext, times(1)).addApplicationListener(same(initializer)); verify(mockApplicationContext, times(1)).registerShutdownHook(); verify(mockApplicationContext, times(1)).register(TestAppConfigOne.class, TestAppConfigTwo.class); //verify(mockApplicationContext, times(1)).register(annotatedClasses(TestAppConfigOne.class, TestAppConfigTwo.class)); //verify(mockApplicationContext, times(1)).register(Matchers.<Class<?>[]>anyVararg()); verify(mockApplicationContext, never()).scan(any(String[].class)); assertEquals(mockApplicationContext, SpringContextBootstrappingInitializer.getApplicationContext()); } @Test public void testInitWithExistingApplicationContext() { ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class, "testInitWithExistingApplicationContext"); when(mockApplicationContext.isActive()).thenReturn(true); when(mockApplicationContext.getId()).thenReturn("testInitWithExistingApplicationContext"); SpringContextBootstrappingInitializer.applicationContext = mockApplicationContext; assertSame(mockApplicationContext, SpringContextBootstrappingInitializer.getApplicationContext()); SpringContextBootstrappingInitializer initializer = new SpringContextBootstrappingInitializer(); initializer.init(createParameters("test", "test")); verify(mockApplicationContext, never()).addApplicationListener(any(SpringContextBootstrappingInitializer.class)); verify(mockApplicationContext, never()).registerShutdownHook(); verify(mockApplicationContext, never()).refresh(); assertSame(mockApplicationContext, SpringContextBootstrappingInitializer.getApplicationContext()); } @Test public void testInitWhenApplicationContextIsNull() { assertNull(SpringContextBootstrappingInitializer.applicationContext); final ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class, "testInitWhenApplicationContextIsNull"); when(mockApplicationContext.getId()).thenReturn("testInitWhenApplicationContextIsNull"); when(mockApplicationContext.isRunning()).thenReturn(true); SpringContextBootstrappingInitializer initializer = new SpringContextBootstrappingInitializer() { @Override protected ConfigurableApplicationContext createApplicationContext(final String[] basePackages, final String[] configLocations) { return mockApplicationContext; } }; initializer.init(createParameters(SpringContextBootstrappingInitializer.CONTEXT_CONFIG_LOCATIONS_PARAMETER, "/path/to/spring/application/context.xml")); verify(mockApplicationContext, times(1)).addApplicationListener(same(initializer)); verify(mockApplicationContext, times(1)).registerShutdownHook(); verify(mockApplicationContext, times(1)).refresh(); assertSame(mockApplicationContext, SpringContextBootstrappingInitializer.getApplicationContext()); } @Test public void testInitWhenApplicationContextIsInactive() { ConfigurableApplicationContext mockInactiveApplicationContext = mock(ConfigurableApplicationContext.class, "testInitWhenApplicationContextIsInactive.Inactive"); when(mockInactiveApplicationContext.isActive()).thenReturn(false); SpringContextBootstrappingInitializer.applicationContext = mockInactiveApplicationContext; assertSame(mockInactiveApplicationContext, SpringContextBootstrappingInitializer.getApplicationContext()); final ConfigurableApplicationContext mockNewApplicationContext = mock(ConfigurableApplicationContext.class, "testInitWhenApplicationContextIsInactive.New"); when(mockNewApplicationContext.getId()).thenReturn("testInitWhenApplicationContextIsInactive.New"); when(mockNewApplicationContext.isRunning()).thenReturn(true); SpringContextBootstrappingInitializer initializer = new SpringContextBootstrappingInitializer() { @Override protected ConfigurableApplicationContext createApplicationContext(final String[] basePackages, final String[] configLocations) { return mockNewApplicationContext; } }; initializer.init(createParameters(SpringContextBootstrappingInitializer.BASE_PACKAGES_PARAMETER, "org.example.app")); verify(mockNewApplicationContext, times(1)).addApplicationListener(same(initializer)); verify(mockNewApplicationContext, times(1)).registerShutdownHook(); verify(mockNewApplicationContext, times(1)).refresh(); assertSame(mockNewApplicationContext, SpringContextBootstrappingInitializer.getApplicationContext()); } @Test public void testInitWhenBasePackagesAndContextConfigLocationsParametersAreUnspecified() throws Throwable { assertThat(SpringContextBootstrappingInitializer.applicationContext, is(nullValue())); expectedException.expect(ApplicationContextException.class); expectedException.expectCause(isA(IllegalArgumentException.class)); expectedException.expectMessage(containsString("Failed to bootstrap the Spring ApplicationContext")); new SpringContextBootstrappingInitializer().init(createParameters(createParameters( SpringContextBootstrappingInitializer.CONTEXT_CONFIG_LOCATIONS_PARAMETER, ""), SpringContextBootstrappingInitializer.BASE_PACKAGES_PARAMETER, " ")); } @Test(expected = IllegalStateException.class) public void testInitWhenApplicationContextIsNotRunning() { assertNull(SpringContextBootstrappingInitializer.applicationContext); final ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class, "testInitWhenApplicationContextIsNotRunning"); when(mockApplicationContext.getId()).thenReturn("testInitWhenApplicationContextIsNotRunning"); when(mockApplicationContext.isRunning()).thenReturn(false); SpringContextBootstrappingInitializer initializer = new SpringContextBootstrappingInitializer() { @Override protected ConfigurableApplicationContext createApplicationContext(final String[] basePackages, final String[] configLocations) { return mockApplicationContext; } }; try { initializer.init(createParameters(SpringContextBootstrappingInitializer.BASE_PACKAGES_PARAMETER, "org.example.app, org.example.plugins")); SpringContextBootstrappingInitializer.getApplicationContext(); } catch (ApplicationContextException expected) { assertTrue(expected.getMessage().contains("Failed to bootstrap the Spring ApplicationContext")); assertTrue(expected.getCause() instanceof IllegalStateException); assertEquals("The Spring ApplicationContext (testInitWhenApplicationContextIsNotRunning) failed to be properly initialized with the context config files ([]) or base packages ([org.example.app, org.example.plugins])!", expected.getCause().getMessage()); throw (IllegalStateException) expected.getCause(); } finally { verify(mockApplicationContext, times(1)).addApplicationListener(same(initializer)); verify(mockApplicationContext, times(1)).registerShutdownHook(); verify(mockApplicationContext, times(1)).refresh(); assertNull(SpringContextBootstrappingInitializer.applicationContext); } } @Test(expected = IllegalStateException.class) public void testInitLogsErrors() throws Throwable { final Log mockLog = mock(Log.class, "testInitLogsErrors.MockLog"); SpringContextBootstrappingInitializer initializer = new SpringContextBootstrappingInitializer() { @Override protected Log initLogger() { return mockLog; } @Override protected ConfigurableApplicationContext createApplicationContext(String[] basePackages, String[] configLocations) { throw new IllegalStateException("TEST"); } }; try { initializer.init(createParameters(SpringContextBootstrappingInitializer.CONTEXT_CONFIG_LOCATIONS_PARAMETER, "classpath/to/spring/application/context.xml")); } catch (ApplicationContextException expected) { assertTrue(expected.getMessage().contains("Failed to bootstrap the Spring ApplicationContext")); assertTrue(expected.getCause() instanceof IllegalStateException); assertEquals("TEST", expected.getCause().getMessage()); throw expected.getCause(); } finally { verify(mockLog, times(1)).error(eq("Failed to bootstrap the Spring ApplicationContext"), any(RuntimeException.class)); } } protected static void assertNotified(TestApplicationListener listener, ApplicationContextEvent expectedEvent) { assertThat(listener, is(notNullValue())); assertThat(listener.isNotified(), is(true)); assertThat(listener.getActualEvent(), is(sameInstance(expectedEvent))); } protected static void assertUnnotified(TestApplicationListener listener) { assertThat(listener, is(notNullValue())); assertThat(listener.isNotified(), is(false)); assertThat(listener.getActualEvent(), is(nullValue())); } @Test public void onContextClosedApplicationEvent() { TestApplicationListener testApplicationListener = new TestApplicationListener( "testOnContextClosedApplicationEvent"); try { testApplicationListener = SpringContextBootstrappingInitializer.register(testApplicationListener); assertUnnotified(testApplicationListener); SpringContextBootstrappingInitializer.contextRefreshedEvent = mock(ContextRefreshedEvent.class, "MockContextRefreshedEvent"); assertThat(SpringContextBootstrappingInitializer.contextRefreshedEvent, isA(ContextRefreshedEvent.class)); new SpringContextBootstrappingInitializer().onApplicationEvent(mock(ContextClosedEvent.class, "MockContextClosedEvent")); assertThat(SpringContextBootstrappingInitializer.contextRefreshedEvent, is(nullValue())); assertUnnotified(testApplicationListener); } finally { SpringContextBootstrappingInitializer.unregister(testApplicationListener); } } @Test public void onContextRefreshedApplicationEvent() { TestApplicationListener testApplicationListener = new TestApplicationListener( "testOnContextRefreshedApplicationEvent"); try { testApplicationListener = SpringContextBootstrappingInitializer.register(testApplicationListener); assertThat(SpringContextBootstrappingInitializer.contextRefreshedEvent, is(nullValue())); assertUnnotified(testApplicationListener); ContextRefreshedEvent mockContextRefreshedEvent = mock(ContextRefreshedEvent.class, "MockContextRefreshedEvent"); new SpringContextBootstrappingInitializer().onApplicationEvent(mockContextRefreshedEvent); assertThat(SpringContextBootstrappingInitializer.contextRefreshedEvent, is(sameInstance(mockContextRefreshedEvent))); assertNotified(testApplicationListener, mockContextRefreshedEvent); } finally { SpringContextBootstrappingInitializer.unregister(testApplicationListener); } } @Test public void onContextStartedApplicationEvent() { TestApplicationListener testApplicationListener = new TestApplicationListener( "testOnContextStartedApplicationEvent"); try { testApplicationListener = SpringContextBootstrappingInitializer.register(testApplicationListener); assertThat(SpringContextBootstrappingInitializer.contextRefreshedEvent, is(nullValue())); assertUnnotified(testApplicationListener); new SpringContextBootstrappingInitializer().onApplicationEvent(mock(ContextStartedEvent.class, "MockContextStartedEvent")); assertThat(SpringContextBootstrappingInitializer.contextRefreshedEvent, is(nullValue())); assertUnnotified(testApplicationListener); } finally { SpringContextBootstrappingInitializer.unregister(testApplicationListener); } } @Test public void onContextStoppedApplicationEvent() { TestApplicationListener testApplicationListener = new TestApplicationListener( "testOnContextStartedApplicationEvent"); try { testApplicationListener = SpringContextBootstrappingInitializer.register(testApplicationListener); assertUnnotified(testApplicationListener); ContextRefreshedEvent mockContextRefreshedEvent = mock(ContextRefreshedEvent.class, "MockContextRefreshedEvent"); SpringContextBootstrappingInitializer.contextRefreshedEvent = mockContextRefreshedEvent; assertThat(SpringContextBootstrappingInitializer.contextRefreshedEvent, is(sameInstance( mockContextRefreshedEvent))); new SpringContextBootstrappingInitializer().onApplicationEvent(mock(ContextStoppedEvent.class, "MockContextStoppedEvent")); assertThat(SpringContextBootstrappingInitializer.contextRefreshedEvent, is(sameInstance(mockContextRefreshedEvent))); assertUnnotified(testApplicationListener); } finally { SpringContextBootstrappingInitializer.unregister(testApplicationListener); } } @Test public void onApplicationEventWithMultipleRegisteredApplicationListeners() { TestApplicationListener testApplicationListenerOne = new TestApplicationListener("TestApplicationListener.1"); TestApplicationListener testApplicationListenerTwo = new TestApplicationListener("TestApplicationListener.2"); TestApplicationListener testApplicationListenerThree = new TestApplicationListener("TestApplicationListener.3"); try { testApplicationListenerOne = SpringContextBootstrappingInitializer.register(testApplicationListenerOne); testApplicationListenerTwo = SpringContextBootstrappingInitializer.register(testApplicationListenerTwo); testApplicationListenerThree = SpringContextBootstrappingInitializer.register(testApplicationListenerThree); assertThat(SpringContextBootstrappingInitializer.contextRefreshedEvent, is(nullValue())); assertUnnotified(testApplicationListenerOne); assertUnnotified(testApplicationListenerTwo); assertUnnotified(testApplicationListenerThree); ContextRefreshedEvent mockContextRefreshedEvent = mock(ContextRefreshedEvent.class, "MockContextRefreshedEvent"); new SpringContextBootstrappingInitializer().onApplicationEvent(mockContextRefreshedEvent); assertThat(SpringContextBootstrappingInitializer.contextRefreshedEvent, is(sameInstance(mockContextRefreshedEvent))); assertNotified(testApplicationListenerOne, mockContextRefreshedEvent); assertNotified(testApplicationListenerTwo, mockContextRefreshedEvent); assertNotified(testApplicationListenerThree, mockContextRefreshedEvent); } finally { SpringContextBootstrappingInitializer.unregister(testApplicationListenerOne); SpringContextBootstrappingInitializer.unregister(testApplicationListenerTwo); SpringContextBootstrappingInitializer.unregister(testApplicationListenerThree); } } @Test public void onApplicationEventWithNoRegisteredApplicationListener() { TestApplicationListener testApplicationListener = new TestApplicationListener("TestApplicationListener"); try { testApplicationListener = SpringContextBootstrappingInitializer.unregister( SpringContextBootstrappingInitializer.register(testApplicationListener)); assertUnnotified(testApplicationListener); new SpringContextBootstrappingInitializer().onApplicationEvent(mock(ContextRefreshedEvent.class, "MockContextRefreshedEvent")); assertUnnotified(testApplicationListener); } finally { SpringContextBootstrappingInitializer.unregister(testApplicationListener); } } @Test public void testNotifyOnExistingContextRefreshedEventBeforeApplicationContextExists() { assertNull(SpringContextBootstrappingInitializer.contextRefreshedEvent); TestApplicationListener testApplicationListener = new TestApplicationListener( "testNotifyOnExistingContextRefreshedEventBeforeApplicationContextExists"); try { testApplicationListener = SpringContextBootstrappingInitializer.register(testApplicationListener); assertUnnotified(testApplicationListener); } finally { SpringContextBootstrappingInitializer.unregister(testApplicationListener); } } @Test public void testNotifyOnExistingContextRefreshedEventAfterContextRefreshed() { ContextRefreshedEvent testContextRefreshedEvent = new ContextRefreshedEvent(mock(ApplicationContext.class)); new SpringContextBootstrappingInitializer().onApplicationEvent(testContextRefreshedEvent); TestApplicationListener testApplicationListener = new TestApplicationListener( "testNotifyOnExistingContextRefreshedEventAfterContextRefreshed"); try { testApplicationListener = SpringContextBootstrappingInitializer.register(testApplicationListener); assertNotified(testApplicationListener, testContextRefreshedEvent); } finally { SpringContextBootstrappingInitializer.unregister(testApplicationListener); } } @Test public void testOnApplicationEventAndNotifyOnExistingContextRefreshedEvent() { ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class, "testOnApplicationEventAndNotifyOnExistingContextRefreshedEvent"); SpringContextBootstrappingInitializer initializer = new SpringContextBootstrappingInitializer(); TestApplicationListener testApplicationListenerOne = new TestApplicationListener( "testOnApplicationEventAndNotifyOnExistingContextRefreshedEvent.1"); TestApplicationListener testApplicationListenerTwo = new TestApplicationListener( "testOnApplicationEventAndNotifyOnExistingContextRefreshedEvent.2"); TestApplicationListener testApplicationListenerThree = new TestApplicationListener( "testOnApplicationEventAndNotifyOnExistingContextRefreshedEvent.3"); try { testApplicationListenerOne = SpringContextBootstrappingInitializer.register(testApplicationListenerOne); assertUnnotified(testApplicationListenerOne); assertUnnotified(testApplicationListenerTwo); assertUnnotified(testApplicationListenerThree); ContextRefreshedEvent testContextRefreshedEvent = new ContextRefreshedEvent(mockApplicationContext); initializer.onApplicationEvent(testContextRefreshedEvent); assertNotified(testApplicationListenerOne, testContextRefreshedEvent); assertUnnotified(testApplicationListenerTwo); assertUnnotified(testApplicationListenerThree); testApplicationListenerTwo = SpringContextBootstrappingInitializer.register(testApplicationListenerTwo); assertNotified(testApplicationListenerTwo, testContextRefreshedEvent); assertUnnotified(testApplicationListenerOne); assertUnnotified(testApplicationListenerThree); ContextStoppedEvent testContextStoppedEvent = new ContextStoppedEvent(mockApplicationContext); initializer.onApplicationEvent(testContextStoppedEvent); assertUnnotified(testApplicationListenerOne); assertUnnotified(testApplicationListenerTwo); assertUnnotified(testApplicationListenerThree); initializer.onApplicationEvent(testContextRefreshedEvent); assertNotified(testApplicationListenerOne, testContextRefreshedEvent); assertNotified(testApplicationListenerTwo, testContextRefreshedEvent); assertUnnotified(testApplicationListenerThree); ContextClosedEvent testContextClosedEvent = new ContextClosedEvent(mockApplicationContext); initializer.onApplicationEvent(testContextClosedEvent); assertUnnotified(testApplicationListenerOne); assertUnnotified(testApplicationListenerTwo); assertUnnotified(testApplicationListenerThree); SpringContextBootstrappingInitializer.register(testApplicationListenerThree); assertUnnotified(testApplicationListenerOne); assertUnnotified(testApplicationListenerTwo); assertUnnotified(testApplicationListenerThree); } finally { SpringContextBootstrappingInitializer.unregister(testApplicationListenerOne); SpringContextBootstrappingInitializer.unregister(testApplicationListenerTwo); SpringContextBootstrappingInitializer.unregister(testApplicationListenerThree); } } @Configuration protected static class TestAppConfigOne { } @Configuration protected static class TestAppConfigTwo { } // TODO add additional multi-threaded test cases once MultithreadedTC test framework is added to the SDP project // in order to properly test concurrency of notification and registration during Spring ApplicationContext creation. protected static class TestApplicationListener implements ApplicationListener<ContextRefreshedEvent> { private volatile boolean notified = false; private volatile ApplicationContextEvent actualEvent; private final String name; public TestApplicationListener(final String name) { this.name = name; } public ApplicationContextEvent getActualEvent() { ApplicationContextEvent localActualEvent = this.actualEvent; this.actualEvent = null; return localActualEvent; } public boolean isNotified() { boolean localNotified = this.notified; this.notified = false; return localNotified; } @Override public void onApplicationEvent(final ContextRefreshedEvent event) { this.actualEvent = event; this.notified = true; } @Override public String toString() { return this.name; } } }