package com.miracle.test.service.util; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.mockito.InjectMocks; import org.mockito.Mock; import org.springframework.aop.framework.Advised; import org.springframework.aop.support.AopUtils; import org.springframework.test.util.ReflectionTestUtils; public final class InjectUtil { private InjectUtil() { } public static void injectTargetForProxyBean(final Object testUnitInstance) throws IllegalAccessException { for (Field injectMocksField : getInjectMocksFields(testUnitInstance.getClass())) { for (Field mockField : getMockFields(testUnitInstance.getClass())) { ReflectionTestUtils.setField(getTarget(injectMocksField.get(testUnitInstance)), mockField.getName(), mockField.get(testUnitInstance)); } } } private static Collection<Field> getInjectMocksFields(final Class<?> clazz) { return getFieldsByAnnotation(clazz, InjectMocks.class); } private static Collection<Field> getMockFields(final Class<?> clazz) { return getFieldsByAnnotation(clazz, Mock.class); } private static Collection<Field> getFieldsByAnnotation(final Class<?> clazz, final Class<? extends Annotation> annotationClass) { Field[] fields = clazz.getDeclaredFields(); List<Field> result = new ArrayList<>(fields.length); for (Field each : fields) { if (null != each.getAnnotation(annotationClass)) { each.setAccessible(true); result.add(each); } } return result; } private static Object getTarget(final Object proxyObj) { if (AopUtils.isAopProxy(proxyObj) && proxyObj instanceof Advised) { try { return ((Advised) proxyObj).getTargetSource().getTarget(); } catch (final Exception ex) { throw new RuntimeException(ex); } } return proxyObj; } }