View Javadoc
1   package uk.org.lidalia.slf4jtest;
2   
3   import java.io.ByteArrayInputStream;
4   import java.io.IOException;
5   import java.io.InputStream;
6   
7   import org.junit.After;
8   import org.junit.Test;
9   import org.junit.runner.RunWith;
10  import org.powermock.core.classloader.annotations.PrepareForTest;
11  import org.powermock.modules.junit4.PowerMockRunner;
12  
13  import uk.org.lidalia.lang.Task;
14  
15  import static org.hamcrest.CoreMatchers.is;
16  import static org.hamcrest.CoreMatchers.sameInstance;
17  import static org.junit.Assert.assertThat;
18  import static org.mockito.Matchers.any;
19  import static org.powermock.api.mockito.PowerMockito.doThrow;
20  import static org.powermock.api.mockito.PowerMockito.mock;
21  import static org.powermock.api.mockito.PowerMockito.mockStatic;
22  import static org.powermock.api.mockito.PowerMockito.when;
23  import static uk.org.lidalia.test.ShouldThrow.shouldThrow;
24  
25  @RunWith(PowerMockRunner.class)
26  @PrepareForTest(OverridableProperties.class)
27  public class OverridablePropertiesTests {
28  
29      private static final String PROPERTY_SOURCE_NAME = "test";
30      private static final String PROPERTY_IN_BOTH = "bothprop";
31      private static final String PROPERTY_IN_SYSTEM_PROPS = "sysprop";
32  
33      @After
34      public void resetLoggerFactory() {
35          System.getProperties().remove(PROPERTY_SOURCE_NAME+"."+PROPERTY_IN_BOTH);
36          System.getProperties().remove(PROPERTY_SOURCE_NAME+"."+PROPERTY_IN_SYSTEM_PROPS);
37      }
38  
39      @Test
40      public void propertyNotInEither() throws IOException {
41          mockPropertyFileToContain("");
42  
43          final String defaultValue = "sensible_default";
44          OverridableProperties properties = new OverridableProperties(PROPERTY_SOURCE_NAME);
45          assertThat(properties.getProperty("notpresent", defaultValue),
46                  is(defaultValue));
47      }
48  
49      @Test
50      public void propertyInFileNotInSystemProperties() throws IOException {
51          final String propName = "infile";
52          final String propValue = "file value";
53          mockPropertyFileToContain(propName + "=" + propValue);
54  
55          OverridableProperties properties = new OverridableProperties(PROPERTY_SOURCE_NAME);
56          assertThat(properties.getProperty(propName, "default"),
57                  is(propValue));
58      }
59  
60      @Test
61      public void propertyNotInFileInSystemProperties() throws IOException {
62          final String expectedValue = "system value";
63          mockPropertyFileToContain("");
64          System.setProperty(PROPERTY_SOURCE_NAME+"."+PROPERTY_IN_SYSTEM_PROPS, expectedValue);
65  
66          OverridableProperties properties = new OverridableProperties("test");
67          assertThat(properties.getProperty(PROPERTY_IN_SYSTEM_PROPS, "default"),
68                  is(expectedValue));
69      }
70  
71      @Test
72      public void propertyInBothFileAndSystemProperties() throws IOException {
73          final String expectedValue = "system value";
74          mockPropertyFileToContain(PROPERTY_IN_BOTH+"=file value");
75          System.setProperty(PROPERTY_SOURCE_NAME+"."+PROPERTY_IN_BOTH, expectedValue);
76  
77          OverridableProperties properties = new OverridableProperties(PROPERTY_SOURCE_NAME);
78          assertThat(properties.getProperty(PROPERTY_IN_BOTH, "default"),
79                  is(expectedValue));
80      }
81  
82      @Test
83      public void noPropertyFile() throws IOException {
84          mockPropertyFileInputStreamToBe(null);
85  
86          OverridableProperties properties = new OverridableProperties(PROPERTY_SOURCE_NAME);
87  
88          final String defaultValue = "sensible_default";
89          assertThat(properties.getProperty("blah", defaultValue), is(defaultValue));
90      }
91  
92      @Test
93      public void ioExceptionLoadingProperties() throws IOException {
94          final IOException ioException = new IOException();
95          final InputStream inputStreamMock = mock(InputStream.class);
96          mockPropertyFileInputStreamToBe(inputStreamMock);
97          when(inputStreamMock.read(any(byte[].class))).thenThrow(ioException);
98  
99          final IOException actual = shouldThrow(IOException.class, new Task() {
100             @Override
101             public void perform() throws Exception {
102                 new OverridableProperties(PROPERTY_SOURCE_NAME);
103             }
104         });
105         assertThat(actual, is(ioException));
106     }
107 
108     @Test
109     public void ioExceptionClosingPropertyStream() throws IOException {
110         final IOException ioException = new IOException();
111         final InputStream inputStreamMock = mock(InputStream.class);
112         mockPropertyFileInputStreamToBe(inputStreamMock);
113         doThrow(ioException).when(inputStreamMock).close();
114 
115 
116         final IOException actual = shouldThrow(IOException.class, new Task() {
117             @Override
118             public void perform() throws Exception {
119                 new OverridableProperties(PROPERTY_SOURCE_NAME);
120             }
121         });
122         assertThat(actual, is(ioException));
123     }
124 
125     @Test
126     public void ioExceptionLoadingAndClosingPropertyStream() throws IOException {
127         final IOException loadException = new IOException("exception on load");
128         final IOException closeException = new IOException("exception on close");
129         final InputStream inputStreamMock = mock(InputStream.class);
130         mockPropertyFileInputStreamToBe(inputStreamMock);
131         when(inputStreamMock.read(any(byte[].class))).thenThrow(loadException);
132         doThrow(closeException).when(inputStreamMock).close();
133 
134         final IOException finalException = shouldThrow(IOException.class, new Task() {
135             @Override
136             public void perform() throws Exception {
137                 new OverridableProperties(PROPERTY_SOURCE_NAME);
138             }
139         });
140         assertThat(finalException, sameInstance(loadException));
141         assertThat(finalException.getSuppressed(), is(new Throwable[]{closeException}));
142     }
143 
144     private void mockPropertyFileToContain(String propertyFileContents) {
145         final ByteArrayInputStream inputStream = new ByteArrayInputStream(propertyFileContents.getBytes());
146         mockPropertyFileInputStreamToBe(inputStream);
147     }
148 
149     private void mockPropertyFileInputStreamToBe(InputStream inputStream) {
150         mockStatic(Thread.class);
151         Thread threadMock = mock(Thread.class);
152         when(Thread.currentThread()).thenReturn(threadMock);
153         ClassLoader classLoaderMock = mock(ClassLoader.class);
154         when(threadMock.getContextClassLoader()).thenReturn(classLoaderMock);
155 
156         when(classLoaderMock.getResourceAsStream(PROPERTY_SOURCE_NAME + ".properties"))
157                 .thenReturn(inputStream);
158     }
159 }