/* * Copyright 2012 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.config.support; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.apache.geode.cache.GemFireCache; import org.apache.geode.cache.Region; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.data.gemfire.util.CollectionUtils; /** * Unit tests for {@link AutoRegionLookupBeanPostProcessor}. * * @author John Blum * @see org.junit.Test * @see org.mockito.Mock * @see org.mockito.Mockito * @see org.mockito.runners.MockitoJUnitRunner * @see org.springframework.data.gemfire.config.support.AutoRegionLookupBeanPostProcessor * @since 1.9.0 */ @RunWith(MockitoJUnitRunner.class) public class AutoRegionLookupBeanPostProcessorUnitTests { @Rule public ExpectedException exception = ExpectedException.none(); private AutoRegionLookupBeanPostProcessor autoRegionLookupBeanPostProcessor; @Mock private ConfigurableListableBeanFactory mockBeanFactory; @Before public void setup() { autoRegionLookupBeanPostProcessor = new AutoRegionLookupBeanPostProcessor(); } protected Region<?, ?> mockRegion(String regionFullPath) { Region<?, ?> mockRegion = mock(Region.class); when(mockRegion.getFullPath()).thenReturn(regionFullPath); when(mockRegion.getName()).thenReturn(toRegionName(regionFullPath)); return mockRegion; } protected String toRegionName(String regionFullPath) { int index = regionFullPath.lastIndexOf(Region.SEPARATOR); return (index > -1 ? regionFullPath.substring(index + 1) : regionFullPath); } @Test public void setAndGetBeanFactory() { autoRegionLookupBeanPostProcessor.setBeanFactory(mockBeanFactory); assertThat(autoRegionLookupBeanPostProcessor.getBeanFactory()).isSameAs(mockBeanFactory); } @Test public void setBeanFactoryToIncompatibleBeanFactoryType() { BeanFactory mockBeanFactory = mock(BeanFactory.class); exception.expect(IllegalArgumentException.class); exception.expectCause(is(nullValue(Throwable.class))); exception.expectMessage(String.format("BeanFactory [%1$s] must be an instance of %2$s", mockBeanFactory.getClass().getName(), ConfigurableListableBeanFactory.class.getSimpleName())); autoRegionLookupBeanPostProcessor.setBeanFactory(mockBeanFactory); } @Test public void setBeanFactoryToNull() { exception.expect(IllegalArgumentException.class); exception.expectCause(is(nullValue(Throwable.class))); exception.expectMessage(String.format("BeanFactory [null] must be an instance of %s", ConfigurableListableBeanFactory.class.getSimpleName())); autoRegionLookupBeanPostProcessor.setBeanFactory(null); } @Test public void getBeanFactoryUninitialized() { exception.expect(IllegalStateException.class); exception.expectCause(is(nullValue(Throwable.class))); exception.expectMessage("BeanFactory was not properly initialized"); autoRegionLookupBeanPostProcessor.getBeanFactory(); } @Test public void postProcessBeforeInitializationReturnsBean() { Object bean = new Object(); assertThat(autoRegionLookupBeanPostProcessor.postProcessBeforeInitialization(bean, "test")).isSameAs(bean); } @Test public void postProcessAfterInitializationWithNonGemFireCacheBean() { Object bean = new Object(); AutoRegionLookupBeanPostProcessor autoRegionLookupBeanPostProcessorSpy = spy(this.autoRegionLookupBeanPostProcessor); assertThat(autoRegionLookupBeanPostProcessorSpy.postProcessAfterInitialization(bean, "test")).isSameAs(bean); verify(autoRegionLookupBeanPostProcessorSpy, never()).registerCacheRegionsAsBeans(any(GemFireCache.class)); } @Test public void registerCacheRegionsAsBeansIsSuccessful() { Set<Region<?, ?>> expected = CollectionUtils.asSet(mockRegion("one"), mockRegion("two"), mockRegion("three")); final Set<Region<?, ?>> actual = new HashSet<Region<?, ?>>(expected.size()); AutoRegionLookupBeanPostProcessor autoRegionLookupBeanPostProcessor = new AutoRegionLookupBeanPostProcessor() { @Override void registerCacheRegionAsBean(Region<?, ?> region) { actual.add(region); } }; GemFireCache mockGemFireCache = mock(GemFireCache.class); when(mockGemFireCache.rootRegions()).thenReturn(expected); autoRegionLookupBeanPostProcessor.registerCacheRegionsAsBeans(mockGemFireCache); assertThat(actual).isEqualTo(expected); verify(mockGemFireCache, times(1)).rootRegions(); for (Region<?, ?> region : expected) { verifyZeroInteractions(region); } } @Test public void registerCacheRegionAsBeanIsSuccessful() { Region<?, ?> mockRegion = mockRegion("Example"); when(mockRegion.subregions(anyBoolean())).thenReturn(Collections.<Region<?, ?>>emptySet()); when(mockBeanFactory.containsBean(anyString())).thenReturn(false); autoRegionLookupBeanPostProcessor.setBeanFactory(mockBeanFactory); autoRegionLookupBeanPostProcessor.registerCacheRegionAsBean(mockRegion); verify(mockBeanFactory, times(1)).containsBean(eq("Example")); verify(mockBeanFactory, times(1)).registerSingleton(eq("Example"), eq(mockRegion)); verify(mockRegion, times(1)).getFullPath(); verify(mockRegion, times(1)).getName(); verify(mockRegion, times(1)).subregions(eq(false)); } @Test public void registerCacheRegionAsBeanRegistersSubRegionIgnoresRootRegion() { Region<?, ?> mockRootRegion = mockRegion("Root"); Region<?, ?> mockSubRegion = mockRegion("/Root/Sub"); when(mockRootRegion.subregions(anyBoolean())).thenReturn(CollectionUtils.<Region<?, ?>>asSet(mockSubRegion)); when(mockSubRegion.subregions(anyBoolean())).thenReturn(Collections.<Region<?, ?>>emptySet()); when(mockBeanFactory.containsBean(eq("Root"))).thenReturn(true); when(mockBeanFactory.containsBean(eq("/Root/Sub"))).thenReturn(false); autoRegionLookupBeanPostProcessor.setBeanFactory(mockBeanFactory); autoRegionLookupBeanPostProcessor.registerCacheRegionAsBean(mockRootRegion); verify(mockBeanFactory, times(1)).containsBean(eq("Root")); verify(mockBeanFactory, times(1)).containsBean(eq("/Root/Sub")); verify(mockBeanFactory, never()).registerSingleton(eq("Root"), eq(mockRootRegion)); verify(mockBeanFactory, times(1)).registerSingleton(eq("/Root/Sub"), eq(mockSubRegion)); verify(mockRootRegion, times(1)).getFullPath(); verify(mockRootRegion, times(1)).getName(); verify(mockRootRegion, times(1)).subregions(eq(false)); verify(mockSubRegion, times(1)).getFullPath(); verify(mockSubRegion, never()).getName(); verify(mockSubRegion, times(1)).subregions(eq(false)); } @Test public void registerNullCacheRegionAsBeanDoesNothing() { autoRegionLookupBeanPostProcessor.setBeanFactory(mockBeanFactory); autoRegionLookupBeanPostProcessor.registerCacheRegionAsBean(null); verifyZeroInteractions(mockBeanFactory); } @Test public void getBeanNameReturnsRegionFullPath() { Region mockRegion = mockRegion("/Parent/Child"); assertThat(autoRegionLookupBeanPostProcessor.getBeanName(mockRegion)).isEqualTo("/Parent/Child"); verify(mockRegion, times(1)).getFullPath(); verify(mockRegion, never()).getName(); } @Test public void getBeanNameReturnsRegionName() { Region mockRegion = mockRegion("/Example"); assertThat(autoRegionLookupBeanPostProcessor.getBeanName(mockRegion)).isEqualTo("Example"); verify(mockRegion, times(1)).getFullPath(); verify(mockRegion, times(1)).getName(); } @Test public void nullSafeSubRegionsWhenSubRegionsIsNotNull() { Set<Region<?, ?>> mockSubRegions = CollectionUtils.asSet(mockRegion("one"), mockRegion("two")); Region mockRegion = mockRegion("parent"); when(mockRegion.subregions(anyBoolean())).thenReturn(mockSubRegions); assertThat(autoRegionLookupBeanPostProcessor.nullSafeSubregions(mockRegion)).isEqualTo(mockSubRegions); verify(mockRegion, times(1)).subregions(eq(false)); } @Test public void nullSafeSubRegionsWhenSubRegionsIsNull() { Region mockRegion = mockRegion("parent"); when(mockRegion.subregions(anyBoolean())).thenReturn(null); assertThat(autoRegionLookupBeanPostProcessor.nullSafeSubregions(mockRegion)).isEqualTo(Collections.emptySet()); verify(mockRegion, times(1)).subregions(eq(false)); } }