способ инициализации Javabean для случайных значений - PullRequest
4 голосов
/ 08 мая 2009

Я искал какой-нибудь служебный класс / код, который бы принимал Java-бин и инициализировал все его значения случайными значениями. Это можно сделать с помощью отражения, так как некоторые библиотеки уже создают методы toString () или equals (). Это полезно при разработке пользовательского интерфейса, чтобы иметь некоторые данные, например.

Другие возможные приятные вещи:

  1. рекурсивная инициализация не примитивных или простых (строка, дата) элементов
  2. инициализировать коллекцию бобов
  3. может дать какой-то способ ограничить сгенерированные значения, например, для чисел, которые мы могли бы дать диапазоны, для регулярных выражений строк или групповых символов ...

кто-нибудь знает что-то подобное? спасибо

РЕДАКТИРОВАТЬ: разрешение ... Получил образец Apocalisp работает и, безусловно, это то, что я искал. У него есть некоторые недостатки ИМХО:

  • Библиотека имеет гораздо большую область применения, но для меня это не проблема
  • Довольно сложно понять, как построить Произвольное для ваших объектов, если вы не потратите некоторое время на изучение всего этого. Это недостаток.
  • И это может быть более кратким, я думаю, но это тоже хорошо.

спасибо!

Ответы [ 6 ]

5 голосов
/ 19 апреля 2016

Взгляните на случайные бобы:

https://github.com/benas/random-beans

Позволяет заполнять граф Java-объекта случайными данными.

Надеюсь, это поможет

С уважением

2 голосов
/ 09 февраля 2012

Хотя я заметил, что этот пост может быть немного старым, у меня просто возникла такая же необходимость, и ни одно из представленных решений, казалось бы, не решило его приемлемо, поэтому я сделал несколько быстрых и грязных пятнадцатиминутных не совсем универсальный служебный метод для генерации случайно заполненных bean-компонентов, который может или не может быть полезен для кого-то, у кого похожая проблема:

import java.beans.PropertyDescriptor;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Random;

import org.springframework.beans.BeanUtils;

public class RandomBeanUtil {

    public static <T> Collection<T> generateTestData(Class<T> clazz, int quantity) {
        Collection<T> list = new ArrayList<T>();

        PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(clazz);
        Random rand = new Random();

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        try {
            for (int i = 0; i != quantity; i++) {
                    T o = clazz.newInstance();

                    for (PropertyDescriptor descriptor : descriptors) {
                        Class<?> type = descriptor.getPropertyType();
                        if (String.class.isAssignableFrom(type)) {
                            descriptor.getWriteMethod().invoke(o, String.valueOf(new char[]{
                                    (char)('A' + rand.nextInt(26)), (char)('a' + rand.nextInt(26)) }));
                        } else if (Date.class.isAssignableFrom(type)) {
                            cal.add(Calendar.DATE, rand.nextInt(60) - 30);
                            descriptor.getWriteMethod().invoke(o, cal.getTime());
                        } else if (BigDecimal.class.isAssignableFrom(type)) {
                            descriptor.getWriteMethod().invoke(o, 
                                    new BigDecimal(rand.nextDouble() * 500).setScale(2, RoundingMode.HALF_UP));
                        }
                    }

                    list.add(o);
            }       
        } catch (Exception e) {
            // TODO: Improve exception handling
            throw new RuntimeException("Error while generating the bean collection", e);
        }

        return list;
    }

}
1 голос
/ 15 мая 2009

Взгляните на класс Gen из библиотеки Reductio . Это часть настраиваемой среды для генерации произвольных значений более или менее любого типа. Предоставляются генераторы для примитивных типов и большинства классов коллекций Java. Вы должны быть в состоянии создать Arbitrary экземпляров для своих классов довольно легко.

РЕДАКТИРОВАТЬ Вот исправленный пример:

import static fj.test.Arbitrary.*;
import static fj.Function.*;

static final Arbitrary<Person> personArbitrary =
  arbitrary(arbInteger.gen.bind(arbString.gen, arbBoolean.gen,
      curry(new F3<Integer, String, Boolean, Person>() {
        public Person f(final Integer age, final String name, final Boolean male)
          {return new Person(age, name, male);}})));

Затем сгенерируйте произвольный Персона "размера 100", вот так. То есть имя будет содержать не более 100 символов.

Person p = personArbitrary.gen.gen(100, Rand.standard);
0 голосов
/ 27 мая 2013

Вы можете делать то, что хотели бы, с помощью библиотеки InPUT с открытым исходным кодом. Он использует определения диапазонов на основе XML-дескрипторов, а не определения в коде. InPUT использует внедрение метода и конструктора, поддерживая сложные объектные структуры произвольной глубины инициализации. Примеры и Доступны учебные пособия .

0 голосов
/ 15 мая 2009

Apache Commons BeanUtils (http://commons.apache.org/beanutils) может быть полезным для вас. Нет никакой утилиты, которую вы могли бы использовать из коробки , но я думаю, что все здание есть блоки, т.е. доступ к свойствам, генераторы случайных чисел.

0 голосов
/ 15 мая 2009

У меня нет библиотеки для вас, но если у вас есть генератор случайных чисел, то, возможно, этот класс пригодится:

public class BeanMethodIterator implements Iterable<Method> {

    private static final int MODIFIER_FILTER = (Modifier.PUBLIC | Modifier.STATIC);
    private static final int MODIFIER_EXPECTED = Modifier.PUBLIC;

    /**
     * Indicator to filter getter or setter methods. 
     */
    public enum Filter {

        /** Only getter methods. */
        GETTERS(new Transform<Method, Boolean>(){
            public Boolean transform(Method input) {
                return (input.getName().startsWith("get") || 
                        input.getName().startsWith("is")) 
                    &&  input.getParameterTypes().length == 0;
            };
        }),

        /** Only setter methods. */
        SETTTERS(new Transform<Method, Boolean>(){
            public Boolean transform(Method input) {
                return input.getName().startsWith("set") && 
                    input.getParameterTypes().length == 1;
            };
        }),

        /** Getter and setter methods. */
        BOTH(new Transform<Method, Boolean>(){
            public Boolean transform(Method input) {
                return Filter.SETTTERS.condition.transform(input) || 
                    Filter.GETTERS.condition.transform(input);
            };
        });

        private Transform<Method, Boolean> condition;

        private Filter(Transform<Method, Boolean> condition) {
            this.condition = condition;
        }

    };

    /**
     * Iterate parent methods also?
     */
    public enum Scope {
        PARENTS_ALSO() {
            @Override
            protected Method[] getMethods(Class<?> c) {
                return c.getMethods();
            };
        },
        THIS_CLASS_ONLY() {
            @Override
            protected Method[] getMethods(Class<?> c) {
                return c.getDeclaredMethods();
            }
        };

        protected abstract Method[] getMethods(Class<?> c);
    }

    private final Filter filter;
    private final Scope scope;
    private final Class<?> theClass;

    /**
     * Constructor. 
     *
     * @param theClass
     * @param what
     */
    public BeanMethodIterator(Class<?> theClass, Filter what, Scope scope) {
        this.filter = what;
        this.theClass = theClass;
        this.scope = scope;
    }

    /**
     * Constructor. 
     */
    public BeanMethodIterator(Class<?> theClass) {
        this(theClass, Filter.BOTH, Scope.PARENTS_ALSO);
    }

    /**
     * Tells if a method is public
     * @param method
     * @return
     */
    private static boolean isPublic(Method method) {
        return (method.getModifiers() & MODIFIER_FILTER) == MODIFIER_EXPECTED; 
    }

    /**
     * {@inheritDoc}
     * @see java.lang.Iterable#iterator()
     */
    public Iterator<Method> iterator() {
        final Method[] methods = this.scope.getMethods(this.theClass);        

        return new Iterator<Method>() {
            int index = 0;

            public boolean hasNext() {
                while (index < methods.length) {
                    if (isPublic(methods[index]) && filter.condition.transform(methods[index]))
                        return true;
                    index++;
                }
                return false;
            }

            public Method next() {
                if (!hasNext())
                    throw new NoSuchElementException();
                return methods[index++];
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }

        };
    }

    public static void main(String[] args) {
        for (Method m: new BeanMethodIterator(Date.class, Filter.GETTERS, Scope.THIS_CLASS_ONLY)) {
            System.out.println(m.getName());
        }
    }

}


/**
 * Represents a function that takes one input and returns a transformation of that input value i.e.
 * a transformation. The name Transform is used because it is shorter.
 * 
 * @author Hannes de Jager
 * @since 01 Sep 2008
 */
interface Transform<I, O> {

    /**
     * Invokes the function, performing the transformation, to produce an interpreted value.
     * 
     * @param input the input value.
     * @return The computed result.
     */
    public O transform(I input);
}
...