接口测试需要给被测的方法塞值,有些非必传的参数也需要你一个个的set值,很麻烦。接触了公司的测试框架后发现可以生成方法的入参模板,给参数生成默认值,可以解决这个问题。
方法中参数的类型有:
简单数据类型:Date Timestamp String StringBuilder Integer Long boolean
集合:List<String> Map<String,Object>
对象:BindOpenIdRequest
对象集合: List<BindOpenIdRequest> List<Map<String,People>>
处理逻辑:
1,简单类型直接返回默认值:String >'a' Integer >0 等
2,集合: List<String> ---['a'] Map<String,Object>--{'a':'a'}
3,对象:BindOpenIdRequest 找出field,给field设置默认值,逻辑同1,2
4,对象集合:List<BindOpenIdRequest> 返回[BindOpenIdRequest],BindOpenIdRequest处理同3
得到方法参数的类型和class列表
Type[] genericParamTypes = method.getGenericParameterTypes();
Class<?>[] paramClasses = method.getParameterTypes();
循环处理每个参数
objectDefaultMaker.getDefaultValue(c, t);
递归处理参数类型,直到找出简单类型表示该参数
private <T> T getSampleObj(Class<T> paramClass, Type t, String fieldName) throws Exception {
if (Collection.class.isAssignableFrom(paramClass)) {
return (T) initCollection((Class<Collection>) paramClass, t);
} else if (paramClass.isArray()) {
return (T) initArray(paramClass, t);
} else if (Map.class.isAssignableFrom(paramClass)) {
return (T) initMap((Class<Map>) paramClass, t);
} else if (paramClass == Date.class) {
return (T) new Date();
} else if (paramClass == Timestamp.class) {
return (T) new Timestamp(System.currentTimeMillis());
} else if (paramClass == String.class || paramClass == StringBuilder.class) {
if (fieldName == null) {
return (T) "a";
}
return (T) (fieldName + "_123");
} else if (paramClass == int.class || paramClass == Integer.class) {
return (T) new Integer(0);
} else if (paramClass == long.class || paramClass == Long.class) {
return (T) new Long(0);
} else if (paramClass == short.class || paramClass == Short.class) {
return (T) new Short((short) 0);
} else if (paramClass == byte.class || paramClass == Byte.class) {
return (T) new Byte((byte) 0);
} else if (paramClass == double.class || paramClass == Double.class) {
return (T) new Double(0.0d);
} else if (paramClass == float.class || paramClass == Float.class) {
return (T) new Float(0.0f);
} else if (paramClass == Boolean.class || paramClass == boolean.class) {
return (T) new Boolean(true);
} else if (paramClass.isEnum() || paramClass == Enum.class) {
T[] ts = paramClass.getEnumConstants();
if (ts.length > 0) {
enumTypes.put(paramClass, ts);
return ts[0];
}
}
return null;
}
private Collection initCollection(Class<Collection> source, Type t) throws Exception {
Collection dest = null;
if (t instanceof ParameterizedType) // 【3】如果是泛型参数的类型
{
ParameterizedType pt = (ParameterizedType) t;
Type[] types = pt.getActualTypeArguments();
Type type0 = types[0];
Class class0 = null;
if (types[0] instanceof ParameterizedType) {
class0 = (Class) ((ParameterizedType) type0).getRawType();
} else {
class0 = (Class) type0;
}
if (Set.class.isAssignableFrom(source)) {
dest = Sets.newHashSet();
} else {
dest = Lists.newArrayList();
}
dest.add(getDefaultValue(class0, type0));
}
return dest;
}
反射常用到的方法
public class People {
public List<String> getLists() {
return lists;
}
public void setLists(List<String> lists) {
this.lists = lists;
}
List<String> lists;
public void say(List<Map<String,String>> list){
System.out.println("哈哈");
}
Method method = People.class.getMethod("say", List.class);
Class c = method.getParameterTypes()[0];
Type t = method.getGenericParameterTypes()[0];
ObjectDefaultValueMaker objectDefaultMaker = new ObjectDefaultValueMaker();
Object result = objectDefaultMaker.getDefaultValue(c, t);
System.out.println(result);
Field field = People.class.getDeclaredField("lists");
System.out.println( field.getGenericType());
System.out.println(field.getType());
结果为:
[{a=a}]
java.util.List<java.lang.String>
interface java.util.List
ParameterizedType (参数化类型)
官方文档的说明是这样
ParameterizedType represents a parameterized type such as
Collection<String>
主要方法:
- Type[] getActualTypeArguments();
- Type getRawType();
- Type getOwnerType();
Type[] getActualTypeArguments(); 返回 这个 Type 类型的参数的实际类型数组。 如 Map<String,Person> map 这个 ParameterizedType 返回的是 String 类,Person 类的全限定类名的 Type Array。
Type getRawType() 返回的是当前这个 ParameterizedType 的类型。 如 Map<String,Person> map 这个 ParameterizedType 返回的是 Map 类的全限定类名的 Type Array。
JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别
获取类的字段有两种方式:getFields()和getDeclaredFields()。
getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
关于field还有一种情况我们需要注意,就是当字段修饰符为private时,我们需要加上:
field.setAccessible(true);
判断方法是:if (!field.isAccessible())