package com.softwaremill.common.cdi.sysprops; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import javax.enterprise.inject.spi.Annotated; import javax.enterprise.inject.spi.InjectionPoint; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static com.softwaremill.common.cdi.sysprops.SystemProperty.NOT_SET; /** * @author Maciej Bilas * @author Marcin Jekot * @since 14/9/12 16:46 */ public class SystemPropertyProducerTest { private static final String TEST_PROPERTY = "SystemPropertyProducerTest.TEST_PROPERTY"; private SystemPropertyProducer service = new SystemPropertyProducer(); @BeforeMethod @AfterClass(alwaysRun = true) private void cleanupSystemProperty() { System.clearProperty(TEST_PROPERTY); } private void setTestProperty(String value) { System.setProperty(TEST_PROPERTY, value); } @Test(expectedExceptions = RuntimeException.class) public void shouldThrowREIfNoConfigValueCanBeFound() { service.produceStringSystemProperty(mockInjectionPointForDefaultTestProperty()); } @Test public void shouldReturnTheSystemPropertyValueWhenFound() { // Given setTestProperty("value"); // When String propertyValue = service.produceStringSystemProperty(mockInjectionPointForDefaultTestProperty()); // Then assertThat(propertyValue).isEqualTo("value"); } @Test public void shouldFallbackToDefaultValueIfSystemPropertyIsNotFound() { // When String propertyValue = service.produceStringSystemProperty( mockInjectionPoint(TEST_PROPERTY, null, "default value")); // Then assertThat(propertyValue).isEqualTo("default value"); } @Test public void shouldTreatKeyAndValueParametersInterchangeablyForPresentValues() { // Given setTestProperty("foo"); // When String obtainedFromSystemPropertyViaValue = service.produceStringSystemProperty( mockInjectionPoint(TEST_PROPERTY, NOT_SET)); String obtainedFromSystemPropertyViaKey = service.produceStringSystemProperty( mockInjectionPoint(TEST_PROPERTY, NOT_SET, NOT_SET)); // Then assertThat(obtainedFromSystemPropertyViaKey).isEqualTo("foo"); assertThat(obtainedFromSystemPropertyViaValue).isEqualTo("foo"); } @Test public void shouldTreatKeyAndValueParametersInterchangeablyForDefaultValues() { // When String obtainedFromSystemPropertyViaValue = service.produceStringSystemProperty( mockInjectionPoint(TEST_PROPERTY, "foo")); String obtainedFromSystemPropertyViaKey = service.produceStringSystemProperty( mockInjectionPoint(TEST_PROPERTY, NOT_SET, "foo")); // Then assertThat(obtainedFromSystemPropertyViaKey).isEqualTo("foo"); assertThat(obtainedFromSystemPropertyViaValue).isEqualTo("foo"); } @Test public void shouldProcessBooleanAsAccordingToBooleanToBooleanMethod() { assertThat(service.produceBooleanSystemProperty( mockInjectionPoint(NOT_SET, TEST_PROPERTY, "true") )).isTrue(); assertThat(service.produceBooleanSystemProperty( mockInjectionPoint(NOT_SET, TEST_PROPERTY, "false") )).isFalse(); assertThat(service.produceBooleanSystemProperty( mockInjectionPoint(NOT_SET, TEST_PROPERTY, "f") )).isFalse(); assertThat(service.produceBooleanSystemProperty( mockInjectionPoint(NOT_SET, TEST_PROPERTY, "yes") // Nope, it's not true )).isFalse(); } @Test public void shouldRetrunBooleanValueFromSystemProperty() { // Given System.setProperty(TEST_PROPERTY, "true"); // When, then assertThat(service .produceBooleanSystemProperty( mockInjectionPoint(TEST_PROPERTY, NOT_SET, NOT_SET))) .isTrue(); } @Test public void shouldThrowInformativeExceptionForInteger() { // Given System.setProperty(TEST_PROPERTY, "not a number"); // When try { service.produceIntegerSystemProperty(mockInjectionPoint(NOT_SET, TEST_PROPERTY, NOT_SET)); } catch (RuntimeException re) { assertThat(re).hasMessage("System property '" + TEST_PROPERTY + "'='not a number' is not a valid Integer"); } } @Test public void shouldThrowInformativeExceptionForDouble() { // Given System.setProperty(TEST_PROPERTY, "not a number"); // When try { service.produceDoubleSystemProperty(mockInjectionPoint(NOT_SET, TEST_PROPERTY, NOT_SET)); } catch (RuntimeException re) { // Then assertThat(re).hasMessage("System property '" + TEST_PROPERTY + "'='not a number' is not a valid Double"); } } @Test public void shouldThrowInformativeExceptionForBigDecimal() { // Given System.setProperty(TEST_PROPERTY, "not a number"); // When try { service.produceBigDecimalSystemProperty(mockInjectionPoint(NOT_SET, TEST_PROPERTY, NOT_SET)); } catch (RuntimeException re) { // Then assertThat(re).hasMessage("System property '" + TEST_PROPERTY + "'='not a number' is not a valid BigDecimal"); } } private InjectionPoint mockInjectionPoint(String value, String key, String defaultValue) { InjectionPoint injectionPoint = mock(InjectionPoint.class); Annotated annotated = mock(Annotated.class); SystemProperty config = mock(SystemProperty.class); when(injectionPoint.getAnnotated()).thenReturn(annotated); when(annotated.getAnnotation(SystemProperty.class)).thenReturn(config); when(config.value()).thenReturn(value); when(config.key()).thenReturn(key); when(config.defaultValue()).thenReturn(defaultValue); return injectionPoint; } private InjectionPoint mockInjectionPoint(String key, String defaultValue) { return mockInjectionPoint(NOT_SET, key, defaultValue); } private InjectionPoint mockInjectionPoint(String value) { return mockInjectionPoint(value, NOT_SET, NOT_SET); } private InjectionPoint mockInjectionPointForDefaultTestProperty() { return mockInjectionPoint(TEST_PROPERTY); } }