ConfigBuilder { public <C> C buildConfig(Class<C> configClass, Properties properties) throws ConfigBuilderException { Map<String, ConfigurationProperty> configPropertiesByName = configPropertyParser.getConfigPropertiesByName(configClass); C configInstance; try { configInstance = configClass.newInstance(); } catch (Exception e) { throw new ConfigBuilderException("Failed to instantiate config class " + configClass.getSimpleName() + " - " + e.getClass().getSimpleName(), e); } List<String> props = configPropertiesByName.keySet().stream().sorted().collect(Collectors.toList()); for ( String configPropertyName : props) { log.debug("Processing config property " + configPropertyName); HandlerConfigPropertyImpl configProperty = (HandlerConfigPropertyImpl)configPropertiesByName.get(configPropertyName); String propertyValue = properties.getProperty(configPropertyName); setValueForConfigProperty(configInstance, configPropertyName, configProperty, propertyValue); } warnOnUnusedProperties(properties, configPropertiesByName); runClassLevelValidation(configClass, configInstance); return configInstance; }  C buildConfig(Class<C> configClass, Properties properties);  }
@Test public void testICanBuildABeanProvidingASimpleStringProperty() throws ConfigBuilderException { Properties p = new Properties(); p.setProperty("stringProperty", "My Provided Value"); ConfigClassWithSimpleProperty c = configBuilder.buildConfig(ConfigClassWithSimpleProperty.class, p); assertEquals("My Provided Value", c.getStringProperty()); }
@Test public void testADefaultValueIsUsedIfIDoNotProvideAValue() throws ConfigBuilderException { Properties p = new Properties(); ConfigClassWithSimpleProperty c = configBuilder.buildConfig(ConfigClassWithSimpleProperty.class, p); assertEquals("My Default Value", c.getStringProperty()); }
@Test public void testValidationRulesAreAppliedToMyProvidedValue() { Properties p = new Properties(); p.setProperty("stringProperty", "This value will not validate"); try { configBuilder.buildConfig(ConfigClassWithSimpleProperty.class, p); fail("Should not validate"); } catch (Exception e) { assertEquals("Property stringProperty value 'This value will not validate' does not match pattern 'My.*'", e.getMessage()); } }
@Test public void testAMandatoryPropertyMustBeProvidedIfADefaultDoesNotExist() { Properties p = new Properties(); try { configBuilder.buildConfig(ConfigClassPropertyWithNoDefault.class, p); fail("Should not validate"); } catch (Exception e) { assertEquals("Property stringProperty is mandatory but no value was provided", e.getMessage()); } }
@Test public void testConfigPropertiesWithEnumField() throws ConfigBuilderException { Properties p = new Properties(); p.setProperty("enumField", "feature"); p.setProperty("enumFieldCaseInsensitive", "ScEnArIo"); ConfigClassWithEnumTypes c = configBuilder.buildConfig(ConfigClassWithEnumTypes.class, p); assertEquals(Scope.FEATURE, c.scope); assertEquals(Scope.SCENARIO, c.scopeCaseInsensitive); }
@Test public void testAnEnumValueWhichCantBeMappedThrowsException() { Properties p = new Properties(); p.setProperty("enumField", "rgioergergerg"); try { ConfigClassWithEnumTypes c = configBuilder.buildConfig(ConfigClassWithEnumTypes.class, p); fail("Should throw exception"); } catch (Exception e) { assertEquals("Property enumField value 'rgioergergerg' does not match pattern '(?i)SCENARIO|FEATURE'", e.getMessage()); } }
@Test public void testUnvalidatedConfigSettersCanAcceptEmptyStringAsValidPropertyValue() throws ConfigBuilderException { Properties p = new Properties(); p.setProperty("stringProperty", ""); ConfigClassWithUnvalidatedStringProperty c = configBuilder.buildConfig(ConfigClassWithUnvalidatedStringProperty.class, p); assertEquals("", c.stringProperty); }