java不用set语句,生成随机对象
本文链接:https://www.cnblogs.com/hchengmx/p/16822991.html
在做测试过程中遇到这样一个问题:造数测试的时候,一个接口的请求入参是个对象,而这个对象里面的层级结构又极其的复杂。一个大对象里面还有若干个小对象。
比如下图的定义结构,不仅包含引用,还包括 List,Array,Date,甚至还有enum。
通常情况下,需要写一堆的set语句,如下图。
TransactionDTO transactionDTO = new TransactionDTO();
transactionDTO.setAcquirerIca(nextInt());
MerchantInfoDTO merchantInfoDTO = new MerchantInfoDTO();
merchantInfoDTO.setMerchantName(randomAlphabetic(6));
merchantInfoDTO.setMerchantId(randomAlphabetic(6));
transactionDTO.setMerchantInfoDTO(merchantInfoDTO);
那么有没有办法不写那么多set语句呢?能否存在一个方法,入参是某个class,出参是这个class对应的随机生成的对象。
private <T> T getRandomObject(Class<T> tClass)
首先可以想到既然有了Class,那就可以得到该Class所有的Field,然后遍历每一个Field。再判断每一个Field的类型,再用field.set方法来set随机生成的值。
这里存在一个小问题,getDeclaredFields()方法只能得到该对象中定义的field,要是存在继承关系,而不能得到父类中的fields,所以不能直接用getDeclaredFields()
要是是Integer类型,就随机生成Integer,
要是Double类型,就随机生成Double,
要是Enum类型,就随机生成Enum
每次只需要判断一下对象的类型是什么,再根据类型生成随机的对象。
比较特殊的有两种情况:
- 要是是个List或者Array,就可以默认生成size为1的值
- 对象里面还有个对象,则又需要遍历里面这个对象中的每一个Field
所以最终两个比较重要的方法如下:
public <T> T generate(Class<T> tClass) {
if (Integer.class.isAssignableFrom(tClass)) {
return (T) getRandomInteger();
} else if (Long.class.isAssignableFrom(tClass)) {
return (T) getRandomLong();
} else if (Double.class.isAssignableFrom(tClass)) {
return (T) getRandomDouble();
} else if (String.class.isAssignableFrom(tClass)) {
return (T) getRandomString();
} else if (BigDecimal.class.isAssignableFrom(tClass)) {
return (T) getRandomBigDecimal();
} else if (Boolean.class.isAssignableFrom(tClass)) {
return (T) getRandomBoolean();
} else if (Date.class.isAssignableFrom(tClass)) {
return (T) getRandomDate();
} else if (Enum.class.isAssignableFrom(tClass)) {
return (T) getRandomEnum(tClass);
} else {
return getRandomObject(tClass);
}
}
private <T> T getRandomObject(Class<T> tClass) {
T instance = tClass.getDeclaredConstructor().newInstance();
List<Field> fields = getDeclaredFields(tClass);
for (Field field : fields.stream().filter(field -> !Modifier.isFinal(field.getModifiers())).collect(Collectors.toList())) {
field.setAccessible(true);
if (List.class.isAssignableFrom(field.getType())) {
Type actualTypeArgument = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
field.set(instance, Arrays.asList(generateRandomArray((Class<?>)actualTypeArgument)));
} else if (field.getType().isArray()) {
field.set(instance, generateRandomArray(field.getType().getComponentType()));
} else {
field.set(instance, generate(field.getType()));
}
}
return instance;
}
最终效果如下,只需要传入一个Class即可得到随机生成的对象。
public static void main(String[] args){
ObjectUtils objectUtils = new ObjectUtils();
TransactionDTO randomObject = objectUtils.generate(TransactionDTO.class);
}
完整代码可参考:java-common/src/main/java/utils/ObjectUtils.java · hchengmx/core-java