/* * Copyright 2002-2016 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.test.context.support; import java.util.Map; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.annotation.AnnotationConfigurationException; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MutablePropertySources; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.ResourceLoader; import org.springframework.mock.env.MockEnvironment; import org.springframework.mock.env.MockPropertySource; import org.springframework.test.context.TestPropertySource; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.CoreMatchers.startsWith; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import static org.springframework.test.context.support.TestPropertySourceUtils.*; /** * Unit tests for {@link TestPropertySourceUtils}. * * @author Sam Brannen * @since 4.1 */ public class TestPropertySourceUtilsTests { private static final String[] EMPTY_STRING_ARRAY = new String[0]; private static final String[] KEY_VALUE_PAIR = new String[] {"key = value"}; private static final String[] FOO_LOCATIONS = new String[] {"classpath:/foo.properties"}; @Rule public ExpectedException expectedException = ExpectedException.none(); @Test public void emptyAnnotation() { expectedException.expect(IllegalStateException.class); expectedException.expectMessage(startsWith("Could not detect default properties file for test")); expectedException.expectMessage(containsString("EmptyPropertySources.properties")); buildMergedTestPropertySources(EmptyPropertySources.class); } @Test public void extendedEmptyAnnotation() { expectedException.expect(IllegalStateException.class); expectedException.expectMessage(startsWith("Could not detect default properties file for test")); expectedException.expectMessage(containsString("ExtendedEmptyPropertySources.properties")); buildMergedTestPropertySources(ExtendedEmptyPropertySources.class); } @Test public void value() { assertMergedTestPropertySources(ValuePropertySources.class, asArray("classpath:/value.xml"), EMPTY_STRING_ARRAY); } @Test public void locationsAndValueAttributes() { expectedException.expect(AnnotationConfigurationException.class); buildMergedTestPropertySources(LocationsAndValuePropertySources.class); } @Test public void locationsAndProperties() { assertMergedTestPropertySources(LocationsAndPropertiesPropertySources.class, asArray("classpath:/foo1.xml", "classpath:/foo2.xml"), asArray("k1a=v1a", "k1b: v1b")); } @Test public void inheritedLocationsAndProperties() { assertMergedTestPropertySources(InheritedPropertySources.class, asArray("classpath:/foo1.xml", "classpath:/foo2.xml"), asArray("k1a=v1a", "k1b: v1b")); } @Test public void extendedLocationsAndProperties() { assertMergedTestPropertySources(ExtendedPropertySources.class, asArray("classpath:/foo1.xml", "classpath:/foo2.xml", "classpath:/bar1.xml", "classpath:/bar2.xml"), asArray("k1a=v1a", "k1b: v1b", "k2a v2a", "k2b: v2b")); } @Test public void overriddenLocations() { assertMergedTestPropertySources(OverriddenLocationsPropertySources.class, asArray("classpath:/baz.properties"), asArray("k1a=v1a", "k1b: v1b", "key = value")); } @Test public void overriddenProperties() { assertMergedTestPropertySources(OverriddenPropertiesPropertySources.class, asArray("classpath:/foo1.xml", "classpath:/foo2.xml", "classpath:/baz.properties"), KEY_VALUE_PAIR); } @Test public void overriddenLocationsAndProperties() { assertMergedTestPropertySources(OverriddenLocationsAndPropertiesPropertySources.class, asArray("classpath:/baz.properties"), KEY_VALUE_PAIR); } @Test public void addPropertiesFilesToEnvironmentWithNullContext() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("must not be null"); addPropertiesFilesToEnvironment((ConfigurableApplicationContext) null, FOO_LOCATIONS); } @Test public void addPropertiesFilesToEnvironmentWithContextAndNullLocations() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("must not be null"); addPropertiesFilesToEnvironment(mock(ConfigurableApplicationContext.class), (String[]) null); } @Test public void addPropertiesFilesToEnvironmentWithNullEnvironment() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("must not be null"); addPropertiesFilesToEnvironment((ConfigurableEnvironment) null, mock(ResourceLoader.class), FOO_LOCATIONS); } @Test public void addPropertiesFilesToEnvironmentWithEnvironmentAndNullLocations() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("must not be null"); addPropertiesFilesToEnvironment(new MockEnvironment(), mock(ResourceLoader.class), (String[]) null); } @Test public void addPropertiesFilesToEnvironmentWithSinglePropertyFromVirtualFile() { ConfigurableEnvironment environment = new MockEnvironment(); MutablePropertySources propertySources = environment.getPropertySources(); propertySources.remove(MockPropertySource.MOCK_PROPERTIES_PROPERTY_SOURCE_NAME); assertEquals(0, propertySources.size()); String pair = "key = value"; ByteArrayResource resource = new ByteArrayResource(pair.getBytes(), "from inlined property: " + pair); ResourceLoader resourceLoader = mock(ResourceLoader.class); when(resourceLoader.getResource(anyString())).thenReturn(resource); addPropertiesFilesToEnvironment(environment, resourceLoader, FOO_LOCATIONS); assertEquals(1, propertySources.size()); assertEquals("value", environment.getProperty("key")); } @Test public void addInlinedPropertiesToEnvironmentWithNullContext() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("context"); addInlinedPropertiesToEnvironment((ConfigurableApplicationContext) null, KEY_VALUE_PAIR); } @Test public void addInlinedPropertiesToEnvironmentWithContextAndNullInlinedProperties() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("inlined"); addInlinedPropertiesToEnvironment(mock(ConfigurableApplicationContext.class), (String[]) null); } @Test public void addInlinedPropertiesToEnvironmentWithNullEnvironment() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("environment"); addInlinedPropertiesToEnvironment((ConfigurableEnvironment) null, KEY_VALUE_PAIR); } @Test public void addInlinedPropertiesToEnvironmentWithEnvironmentAndNullInlinedProperties() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("inlined"); addInlinedPropertiesToEnvironment(new MockEnvironment(), (String[]) null); } @Test public void addInlinedPropertiesToEnvironmentWithMalformedUnicodeInValue() { expectedException.expect(IllegalStateException.class); expectedException.expectMessage("Failed to load test environment property"); addInlinedPropertiesToEnvironment(new MockEnvironment(), asArray("key = \\uZZZZ")); } @Test public void addInlinedPropertiesToEnvironmentWithMultipleKeyValuePairsInSingleInlinedProperty() { expectedException.expect(IllegalStateException.class); expectedException.expectMessage("Failed to load exactly one test environment property"); addInlinedPropertiesToEnvironment(new MockEnvironment(), asArray("a=b\nx=y")); } @Test @SuppressWarnings("rawtypes") public void addInlinedPropertiesToEnvironmentWithEmptyProperty() { ConfigurableEnvironment environment = new MockEnvironment(); MutablePropertySources propertySources = environment.getPropertySources(); propertySources.remove(MockPropertySource.MOCK_PROPERTIES_PROPERTY_SOURCE_NAME); assertEquals(0, propertySources.size()); addInlinedPropertiesToEnvironment(environment, asArray(" ")); assertEquals(1, propertySources.size()); assertEquals(0, ((Map) propertySources.iterator().next().getSource()).size()); } @Test public void convertInlinedPropertiesToMapWithNullInlinedProperties() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("inlined"); convertInlinedPropertiesToMap((String[]) null); } private static void assertMergedTestPropertySources(Class<?> testClass, String[] expectedLocations, String[] expectedProperties) { MergedTestPropertySources mergedPropertySources = buildMergedTestPropertySources(testClass); assertNotNull(mergedPropertySources); assertArrayEquals(expectedLocations, mergedPropertySources.getLocations()); assertArrayEquals(expectedProperties, mergedPropertySources.getProperties()); } @SafeVarargs private static <T> T[] asArray(T... arr) { return arr; } @TestPropertySource static class EmptyPropertySources { } @TestPropertySource static class ExtendedEmptyPropertySources extends EmptyPropertySources { } @TestPropertySource(locations = "/foo", value = "/bar") static class LocationsAndValuePropertySources { } @TestPropertySource("/value.xml") static class ValuePropertySources { } @TestPropertySource(locations = { "/foo1.xml", "/foo2.xml" }, properties = { "k1a=v1a", "k1b: v1b" }) static class LocationsAndPropertiesPropertySources { } static class InheritedPropertySources extends LocationsAndPropertiesPropertySources { } @TestPropertySource(locations = { "/bar1.xml", "/bar2.xml" }, properties = { "k2a v2a", "k2b: v2b" }) static class ExtendedPropertySources extends LocationsAndPropertiesPropertySources { } @TestPropertySource(locations = "/baz.properties", properties = "key = value", inheritLocations = false) static class OverriddenLocationsPropertySources extends LocationsAndPropertiesPropertySources { } @TestPropertySource(locations = "/baz.properties", properties = "key = value", inheritProperties = false) static class OverriddenPropertiesPropertySources extends LocationsAndPropertiesPropertySources { } @TestPropertySource(locations = "/baz.properties", properties = "key = value", inheritLocations = false, inheritProperties = false) static class OverriddenLocationsAndPropertiesPropertySources extends LocationsAndPropertiesPropertySources { } }