org.test4j.module.inject.proxy.FieldProxy Maven / Gradle / Ivy
package org.test4j.module.inject.proxy;
import org.test4j.Context;
import org.test4j.mock.Stubs;
import org.test4j.mock.stub.ProxyInvocation;
import org.test4j.mock.stub.ProxyInvokable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 目标对象字段的代理
* 用于运行时动态获得目标对象字段的实际值调用
*
* @author darui.wudr
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public class FieldProxy implements ProxyInvokable {
private final String fieldName;
private final Field accessor;
public FieldProxy(final Class target, final String fieldName) {
this.fieldName = fieldName;
this.accessor = InjectHelper.getField(target, fieldName);
this.accessor.setAccessible(true);
}
@Override
public Object invoke(ProxyInvocation invocation) throws Throwable {
Object fieldValue = accessor.get(Context.currTestObject());
if (fieldValue == null) {
throw new NullPointerException(String.format("field[%s] value is null.", fieldName));
}
try {
Method method = invocation.getMethod();
Object[] paras = invocation.getParametersAsArray();
boolean accessible = method.isAccessible();
if (!accessible) {
method.setAccessible(true);
}
Object o = method.invoke(fieldValue, paras);
if (!accessible) {
method.setAccessible(false);
}
return o;
} catch (Throwable e) {
if (e instanceof InvocationTargetException) {
throw ((InvocationTargetException) e).getTargetException();
} else {
throw e;
}
}
}
/**
* 构造一个代理类,将代理类的操作转移到testedObject属性 (fieldName)对象上
* 构造一个type类型的mock spring bean
*
* @param type
* @param testClazz 测试类
* @param field 属性
* @return ignore
*/
public static T proxy(final Class testClazz, final Field field) {
FieldProxy handler = new FieldProxy(testClazz, field.getName());
Class type = field.getType();
return (T) Stubs.proxy(handler, type);
}
}