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

每次只需要判断一下对象的类型是什么,再根据类型生成随机的对象。

比较特殊的有两种情况:

  1. 要是是个List或者Array,就可以默认生成size为1的值
  2. 对象里面还有个对象,则又需要遍历里面这个对象中的每一个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

posted on 2022-10-24 21:07  hchengmx  阅读(249)  评论(0编辑  收藏  举报