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

io.mats3.spring.test.SpringInjectRulesAndExtensions Maven / Gradle / Ivy

Go to download

Mats^3 Spring-specific testing tools, for quickly firing up a test-harness using either JUnit or Jupiter (JUnit 5).

The newest version!
package io.mats3.spring.test;

import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.TestExecutionListener;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.TestExecutionListeners.MergeMode;
import org.springframework.test.context.support.AbstractTestExecutionListener;

import io.mats3.spring.test.SpringInjectRulesAndExtensions.SpringInjectRulesAndExtensionsTestExecutionListener;

/**
 * Use this Test Execution Listener to autowire JUnit Rules and Jupiter Extensions, i.e. so that any fields in the Rule
 * or Extension annotated with @Inject or @Autowire will be autowired - typically needed for
 * Rule_MatsEndpoint and Extension_MatsEndpoint.
 * 

* To use, just put this annotation on the test class. If that fails, typically because you are also employing a * different TestExecutionListener, a fallback is to directly list the * {@link SpringInjectRulesAndExtensionsTestExecutionListener} in the @TestExecutionListeners annotation on * the test class, as such: * *

 * {@literal @}TestExecutionListeners(listeners = SpringInjectRulesAndExtensionsTestExecutionListener.class, mergeMode = MergeMode.MERGE_WITH_DEFAULTS)
 * 
* * @author Kevin Mc Tiernan, 2020-11-03, [email protected] * @author Endre Stølsvik 2020-11-24 23:16 - http://stolsvik.com/, [email protected] */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @TestExecutionListeners(listeners = SpringInjectRulesAndExtensionsTestExecutionListener.class, mergeMode = MergeMode.MERGE_WITH_DEFAULTS) @Documented public @interface SpringInjectRulesAndExtensions { /** * This {@link TestExecutionListener} finds all fields in the test class instance which is annotated with JUnit * Rule or JUnit 5 Jupiter RegisterExtension, and runs * beanFactory.autowireBean(fieldValue) on them. */ class SpringInjectRulesAndExtensionsTestExecutionListener extends AbstractTestExecutionListener { /** * Performs dependency injection on Rule and @RegisterExtension fields in test-class * as supplied by testContext. */ @Override public void prepareTestInstance(TestContext testContext) { AutowireCapableBeanFactory beanFactory = testContext.getApplicationContext() .getAutowireCapableBeanFactory(); // Get all fields in test class annotated with @Rule or @RegisterExtension Set testRuleFields = findFields(testContext.getTestClass(), "org.junit.Rule"); Set testExtensionFields = findFields(testContext.getTestClass(), "org.junit.jupiter.api.extension.RegisterExtension"); Set allFields = new HashSet<>(); allFields.addAll(testRuleFields); allFields.addAll(testExtensionFields); // Use bean factory to autowire all extensions for (Field testField : allFields) { try { // We need to set this accessible, even for public fields, as Java 17s access controls will // prevent access otherwise. testField.setAccessible(true); Object ruleObject = testField.get(testContext.getTestInstance()); beanFactory.autowireBean(ruleObject); } catch (Exception e) { throw new AssertionError("Failed read field [" + testField + "] in [" + testField.getClass() + "]," + " unable to autowire it as a bean in test class [" + testContext.getTestClass() + "]", e); } } } /** * Find all fields in class with given annotation. Amended from StackOverflow, inspired by Apache Commons Lang. *

* https://stackoverflow.com/a/29766135 */ @SuppressWarnings("unchecked") protected static Set findFields(Class clazz, String annotationClassName) { try { Class annotationClass = (Class) Class.forName( annotationClassName); Set set = new HashSet<>(); Class c = clazz; while (c != null) { for (Field field : c.getDeclaredFields()) { if (field.isAnnotationPresent(annotationClass)) { set.add(field); } } c = c.getSuperclass(); } return set; } catch (ClassNotFoundException e) { return Collections.emptySet(); } } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy