All Downloads are FREE. Search and download functionalities are using the official Maven repository.

info.novatec.testit.webtester.junit5.extensions.configuration.ConfigurationValueExtension Maven / Gradle / Ivy

There is a newer version: 2.10.3
Show newest version
package info.novatec.testit.webtester.junit5.extensions.configuration;

import java.lang.reflect.Field;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.Extension;
import org.junit.jupiter.api.extension.ExtensionContext;

import lombok.extern.slf4j.Slf4j;

import info.novatec.testit.webtester.browser.Browser;
import info.novatec.testit.webtester.config.Configuration;
import info.novatec.testit.webtester.junit5.extensions.BaseExtension;
import info.novatec.testit.webtester.junit5.extensions.NoManagedBrowserException;
import info.novatec.testit.webtester.junit5.extensions.NoManagedBrowserForNameException;
import info.novatec.testit.webtester.junit5.extensions.UnknownConfigurationKeyException;
import info.novatec.testit.webtester.junit5.extensions.browsers.Managed;
import info.novatec.testit.webtester.junit5.extensions.configuration.unmarshaller.BooleanUnmarshaller;
import info.novatec.testit.webtester.junit5.extensions.configuration.unmarshaller.ConfigurationUnmarshaller;
import info.novatec.testit.webtester.junit5.extensions.configuration.unmarshaller.DefaultUnmarshaller;
import info.novatec.testit.webtester.junit5.extensions.configuration.unmarshaller.DoubleUnmarshaller;
import info.novatec.testit.webtester.junit5.extensions.configuration.unmarshaller.FloatUnmarshaller;
import info.novatec.testit.webtester.junit5.extensions.configuration.unmarshaller.IntegerUnmarshaller;
import info.novatec.testit.webtester.junit5.extensions.configuration.unmarshaller.LongUnmarshaller;
import info.novatec.testit.webtester.junit5.extensions.configuration.unmarshaller.StringUnmarshaller;
import info.novatec.testit.webtester.junit5.internal.TestClassModel;


/**
 * This {@link Extension} resolves and injects {@link Configuration} property values into fields annotated with {@link
 * ConfigurationValue}. This is done before the first {@link BeforeEach} method is invoked.
 * 

* For this injection the field's type is evaluated and a matching {@link ConfigurationUnmarshaller} looked up. Out of * the box the following types can be resolved: *

    *
  • {@link String}
  • *
  • {@link Boolean}
  • *
  • {@link Integer}
  • *
  • {@link Long}
  • *
  • {@link Float}
  • *
  • {@link Double}
  • *
* To use a custom {@link ConfigurationUnmarshaller} a class reference must be specified as {@link * ConfigurationValue#using()}. *

* In case the test is declaring multiple {@link Managed} {@link Browser} instances each must have a unique name and the * {@link ConfigurationValue#source()} property must be specified! *

* Example: *

 * @EnableWebTesterExtensions
 * public class FooTest {
 *
 *     @Managed
 *     Browser browser;
 *
 *     @ConfigurationValue("keys.foo")
 *     String value;
 *
 *     @ConfigurationValue(value="keys.foo", using=FooUnmarshaller.class)
 *     Foo fooValue;
 *
 * }
 *
 * @EnableWebTesterExtensions
 * public class BarTest {
 *
 *     @Managed("b1")
 *     Browser browser1;
 *     @Managed("b2")
 *     Browser browser2;
 *
 *     @ConfigurationValue(value="keys.foo", source="b2")
 *     String value;
 *
 * }
 * 
* * @see ConfigurationValue * @see ConfigurationUnmarshaller * @see Configuration * @since 2.1 */ @Slf4j public class ConfigurationValueExtension extends BaseExtension implements BeforeEachCallback { @SuppressWarnings("unchecked") private static final List> DEFAULT_UNMARSHALLERS = new ArrayList() {{ add(new StringUnmarshaller()); add(new BooleanUnmarshaller()); add(new IntegerUnmarshaller()); add(new LongUnmarshaller()); add(new FloatUnmarshaller()); add(new DoubleUnmarshaller()); }}; @Override @SuppressWarnings("PMD.SignatureDeclareThrowsException") public void beforeEach(ExtensionContext context) throws Exception { executeHandlingUndeclaredThrowables(context, ctx -> { TestClassModel model = getModel(ctx); Object testInstance = ctx.getRequiredTestInstance(); injectValuesIntoAnnotatedFields(model, testInstance); }); } void injectValuesIntoAnnotatedFields(TestClassModel model, Object testInstance) { List valueFields = model.getConfigurationValueFields(); if (valueFields.isEmpty()) { log.debug("no configuration value fields to initialize"); return; } Map map = model.getNamedBrowserFields(); if (map.isEmpty()) { throw new NoManagedBrowserException(); } valueFields.forEach(field -> { ConfigurationValue annotation = field.getAnnotation(ConfigurationValue.class); String browserName = annotation.source(); Field browserField = map.get(browserName); if (browserField == null) { throw new NoManagedBrowserForNameException(browserName); } Browser browser = getValue(browserField, testInstance); Configuration config = browser.configuration(); String key = getKey(field); Class type = field.getType(); Object value; if (DefaultUnmarshaller.class.equals(annotation.using())) { value = getValueUsingDefaultGetters(config, key, type); } else { ConfigurationUnmarshaller unmarshaller = createConfigurationUnmarshaller(annotation); if (unmarshaller.canHandle(type)) { value = unmarshaller.unmarshal(config, key).orElseThrow(() -> new UnknownConfigurationKeyException(key)); } else { throw new UnmarshallerCantHandleTypeException(unmarshaller.getClass(), type); } } setValue(field, testInstance, value); }); } private ConfigurationUnmarshaller createConfigurationUnmarshaller(ConfigurationValue annotation) { ConfigurationUnmarshaller unmarshaller; try { unmarshaller = annotation.using().newInstance(); } catch (InstantiationException | IllegalAccessException e) { throw new UndeclaredThrowableException(e); } return unmarshaller; } private String getKey(Field field) { return field.getAnnotation(ConfigurationValue.class).value(); } private Object getValueUsingDefaultGetters(Configuration config, String key, Class type) { return DEFAULT_UNMARSHALLERS.stream() .filter(resolver -> resolver.canHandle(type)) .findFirst() .orElseThrow(() -> new NoConfigurationUnmarshallerFoundException(type)) .unmarshal(config, key) .orElseThrow(() -> new UnknownConfigurationKeyException(key)); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy