單元測試數據構造工具

調用newData方法,傳入指定BeanClass類型,自動根據set方法構建隨機數據,注意,這裏的set方法是指屬性的set方法!具體用法參見代碼的main方法。

public class Tools {

    public static final String SAMPLE_CODE = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    public static final Map<String, Class<?>> BASIC_DATA_TYPE_MAP = new HashMap<>();

    static {
        BASIC_DATA_TYPE_MAP.put("int", Integer.class);
        BASIC_DATA_TYPE_MAP.put("double", Double.class);
        BASIC_DATA_TYPE_MAP.put("long", Long.class);
        BASIC_DATA_TYPE_MAP.put("short", Short.class);
        BASIC_DATA_TYPE_MAP.put("byte", Byte.class);
        BASIC_DATA_TYPE_MAP.put("boolean", Boolean.class);
        BASIC_DATA_TYPE_MAP.put("char", Character.class);
        BASIC_DATA_TYPE_MAP.put("float", Float.class);
    }

    /**
     * 隨機字符串
     * @param length
     * @return
     */
    public static String getRandomString(int length) {
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(SAMPLE_CODE.length());
            sb.append(SAMPLE_CODE.charAt(number));
        }
        return sb.toString();
    }

    public static Date getNow() {
        return new Date();
    }

    /**
     * 隨機數字,轉換成對應的包裝類型,對於Boolean類型的數據,總是返回false
     * @param length
     * @param clazz
     * @param <T>
     * @return
     * @throws Exception
     */
    public static <T> T getRandomNumber(int length, Class<?> clazz) throws Exception {

        if (length <= 0) {
            length = 1;
        }

        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        while (sb.length() < length) {
            sb.append(random.nextInt(10));
        }
        String str = sb.toString();
        if (clazz.isPrimitive()) {
            clazz = BASIC_DATA_TYPE_MAP.get(clazz.getName());
        }
        Constructor<?> constructor = clazz.getConstructor(String.class);
        Object result = constructor.newInstance(str);
        return (T) result;
    }

    /**
     * 構造數據,你的對象一定要有無參構造函數
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T newData(Class<?> clazz) {
        try {
            Object obj = clazz.newInstance();
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                if (method.getName().startsWith("set")) {
                    Class<?>[] parameterTypes = method.getParameterTypes();
                    Class<?> type = parameterTypes[0];
                    method.invoke(obj, dispatcher(type));
                }
            }
            return (T) obj;
        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalArgumentException();
        }
    }

    /**
     * 適配數據類型
     *
     * @param clazz
     * @param <T>
     * @return
     * @throws Exception
     */
    public static <T> T dispatcher(Class<?> clazz) throws Exception {

        if (isPrimitive(clazz)) {
            return getRandomNumber(0, clazz);
        } else if (clazz.isAssignableFrom(Date.class)) {
            return (T) getNow();
        } else if (clazz.isAssignableFrom(String.class)) {
            return (T) getRandomString(6);
        } else if (clazz.isInterface()) {
            if (clazz.isAssignableFrom(List.class)) {
                // 返回的集合不能添加數據
                // return (T) Collections.emptyList();
                return null;
            } else if (clazz.isAssignableFrom(Map.class)) {
                // 返回的集合不能添加數據
                // return (T) Collections.EMPTY_MAP;
                return null;
            } else if (clazz.isAssignableFrom(Set.class)) {
                // 返回的集合不能添加數據
                // return (T) Collections.EMPTY_SET;
                return null;
            }
            return null;
        } else {
            // Object
            return (T) clazz.newInstance();
        }
    }

    /**
     * 判斷基本數據類型和包裝類型
     *
     * @param clazz
     * @return
     */
    public static boolean isPrimitive(Class<?> clazz) {
        try {
            // 判斷基本數據類型
            if (clazz.isPrimitive()) {
                return true;
            }
            // 判斷包裝類型
            if (clazz.getField("TYPE") != null && ((Class) (clazz.getField("TYPE").get(null))).isPrimitive()) {
                return true;
            }
        } catch (Exception e) {
        }
        return false;
    }

    public static void main(String[] args) throws Exception {
        Goods goods = newData(Goods.class);
        List<String> ext = new ArrayList<>();
        goods.setExt(ext);
        ext.add("集合要自己創建");
        System.out.println(goods);
    }

    static class Goods {
   		public Goods(){}
        private String name;
        private Integer count;
        private Double price;
        private List<String> ext;
        private Byte byt;
        private Boolean flag;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Integer getCount() {
            return count;
        }
        public void setCount(Integer count) {
            this.count = count;
        }
        public Double getPrice() {
            return price;
        }
        public void setPrice(Double price) {
            this.price = price;
        }
        public List<String> getExt() {
            return ext;
        }
        public void setExt(List<String> ext) {
            this.ext = ext;
        }
        public Byte getByt() {
            return byt;
        }
        public void setByt(Byte byt) {
            this.byt = byt;
        }
        public Boolean getFlag() {
            return flag;
        }
        public void setFlag(Boolean flag) {
            this.flag = flag;
        }
        @Override
        public String toString() {
            return "Goods{" + "name='" + name + '\'' + ", count=" + count + ", price=" + price + ", ext=" + ext + ", byt=" + byt + ", flag=" + flag + '}';
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章