web-dev-qa-db-fra.com

Remplir les propriétés primitives avec des données aléatoires automatiquement?

Existe-t-il une bibliothèque Java qui aiderait à créer des instances de classes à tester? Celui qui examine les propriétés d’un haricot et le remplit de données aléatoires.
Je recherche un équivalent Java de Object Hydrator for C #. 

35
prasopes

Vous pouvez utiliser PoDaM :

PodamFactory factory = new PodamFactoryImpl();
Pojo myPojo = factory.manufacturePojo(Pojo.class);
43
pk1

Jetez un coup d'oeil aux haricots aléatoires:

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

Il vous permet de renseigner un graphe d'objet Java avec des données aléatoires.

J'espère que ça aide Cordialement

19
Mahmoud Ben Hassine

Je ne connais pas de cadre, mais c'est assez simple d'en écrire un vous-même. La complexité provient de propriétés non simples, également appelées associations d'objets. Quelque chose comme ça gère les bases et quelques autres:

public static void randomlyPopulateFields(Object object) {
    new RandomValueFieldPopulator().populate(object);
}

public static class RandomValueFieldPopulator {
    public void populate(Object object) {
        ReflectionUtils.doWithFields(object.getClass(), new RandomValueFieldSetterCallback(object));
    }

    private static class RandomValueFieldSetterCallback implements FieldCallback {
        private Object targetObject;

        public RandomValueFieldSetterCallback(Object targetObject) {
            this.targetObject = targetObject;
        }

        @Override
        public void doWith(Field field) throws IllegalAccessException {
            Class<?> fieldType = field.getType();
            if (!Modifier.isFinal(field.getModifiers())) {
                Object value = generateRandomValue(fieldType, new WarnOnCantGenerateValueHandler(field));
                if (!value.equals(UNGENERATED_VALUE_MARKER)) {
                    ReflectionUtils.makeAccessible(field);
                    field.set(targetObject, value);
                }
            }
        }
    }
}

public static Object generateRandomValue(Class<?> fieldType, CantGenerateValueHandler cantGenerateValueHandler) {
    if (fieldType.equals(String.class)) {
        return UUID.randomUUID().toString();
    } else if (Date.class.isAssignableFrom(fieldType)) {
        return new Date(System.currentTimeMillis() - random.nextInt(DATE_WINDOW_MILLIS));
    } else if (Number.class.isAssignableFrom(fieldType)) {
        return random.nextInt(Byte.MAX_VALUE) + 1;
    } else if (fieldType.equals(Integer.TYPE)) {
        return random.nextInt();
    } else if (fieldType.equals(Long.TYPE)) {
        return random.nextInt();
    } else if (Enum.class.isAssignableFrom(fieldType)) {
        Object[] enumValues = fieldType.getEnumConstants();
        return enumValues[random.nextInt(enumValues.length)];
    } else {
        return cantGenerateValueHandler.handle();
    }
}
13
Ryan Stewart

Vous pouvez commander randomizer pour la génération de données aléatoires.Cette bibliothèque permet de créer des données aléatoires à partir de la classe Model donnée.Vérifier ci-dessous le code de l'exemple.

public class Person {

   @FirstName
   String mFirstName;

   @LastName
   String mLastName;

   @Number(min = 14,max = 25,decimals = 0)
   int age;

   @DateValue( from = "01 Jan 1990",to = "31 Dec 2002" , customFormat = "dd MMM yyyy")
   String dateOfBirth;

   @Email
   String  mEmailId;

   @StreetAddress
   public String streetAddress;

   @State
   public String state;

   //Person can have minimum 1 Phone number and maximum 3 phone number
   @Phone(country = Phone.Country.INDIA)
   @CollectionDescriptor(min = 1,max = 3) 
   List<String> phones;

}

//Generate random 100 Person(Model Class) object 
Generator<Person> generator = new Generator<>(Person.class);  
List<Person> persons = generator.generate(100);                          

Comme de nombreux générateurs de données intégrés sont accessibles à l'aide d'annotations, vous pouvez également créer un générateur de données personnalisé. Je vous suggère de consulter la documentation fournie sur la page de la bibliothèque. 

5
Ronak Poriya

https://github.com/benas/random-beans a fait le travail pour moi, alors que PoDam échouait avec des séparateurs "fluents" et que la réponse de Ryan Stewart n'était pas complète pour le copier-coller, comme le font les classes non exposé! Avec random-beans c'est aussi simple que:

Auction auction = EnhancedRandom.random(Auction.class);

Gradle:

testCompile ('io.github.benas:random-beans:3.4.0')
5
Juri Reinsalu

Pour les tests, notre groupe a eu du succès avec JUnit et Mockito. Voici un lien vers une réponse Mockito .

Je ne suis pas sûr que le remplissage avec des données aléatoires soit un test significatif. Peut-être un test plus significatif consisterait-il à tester les conditions normales, limites et d'erreur.

1
rajah9

J'ai utilisé la réflexion et la récursion ici pour obtenir tous les champs renseignés dans mon objet robuste que je souhaitais tester. C’est utiliser PODAM et j’espère que quelqu'un trouvera cela utile.

public class Populate {

    private final PodamFactory podamFactory = new PodamFactoryImpl();

    private <P> P getManufacturedPojo(final Class<P> klass) {
        return podamFactory.manufacturePojo(klass);
    }

    private Object populateAllIn(final Class targetClass) throws IllegalAccessException, InstantiationException {
        final Object target = targetClass.newInstance();

        //Get all fields present on the target class
        final Set<Field> allFields = getAllFields(targetClass, Predicates.<Field>alwaysTrue());

        //Iterate through fields
        for (final Field field : allFields) {

            //Set fields to be accessible even when private
            field.setAccessible(true);

            final Class<?> fieldType = field.getType();
            if (fieldType.isEnum() && EnrichmentType.class.isAssignableFrom(fieldType)) {
                 //handle any enums here if you have any
            }              

            //Check if the field is a collection
            if (Collection.class.isAssignableFrom(fieldType)) {

                //Get the generic type class of the collection
                final Class<?> genericClass = getGenericClass(field);

                //Check if the generic type of a list is abstract
                if (Modifier.isAbstract(genericClass.getModifiers())) {

                    //You might want to use any class that extends
                    //Your abstract class like 

                    final List<Object> list = new ArrayList<>();
                    list.add(populateAllIn(ClassExtendingAbstract.class));
                    field.set(target, list);

                } else {
                    final List<Object> list = new ArrayList<>();
                    list.add(populateAllIn(genericClass));
                    field.set(target, list);
                }

            } else if ((isSimpleType(fieldType) || isSimplePrimitiveWrapperType(fieldType)) && !fieldType.isEnum()) {
                field.set(target, getManufacturedPojo(fieldType));

            } else if (!fieldType.isEnum()) {
                field.set(target, populateAllIn(fieldType));
            }
        }
        return target;
    }

Et quelques méthodes d'assistance. Le code peut ne pas être parfait mais fonctionne :).

private Class<?> getGenericClass(final Field field) {
    final ParameterizedType collectionType = (ParameterizedType) field.getGenericType();
    return (Class<?>) collectionType.getActualTypeArguments()[0];
}

private boolean isSimpleType(final Class<?> fieldType) {
    return fieldType.isPrimitive()
            || fieldType.isEnum()
            || String.class.isAssignableFrom(fieldType)
            || Date.class.isAssignableFrom(fieldType);
}

private boolean isSimplePrimitiveWrapperType(final Class<?> fieldType) {
    return Integer.class.isAssignableFrom(fieldType)
            || Boolean.class.isAssignableFrom(fieldType)
            || Character.class.isAssignableFrom(fieldType)
            || Long.class.isAssignableFrom(fieldType)
            || Short.class.isAssignableFrom(fieldType)
            || Double.class.isAssignableFrom(fieldType)
            || Float.class.isAssignableFrom(fieldType)
            || Byte.class.isAssignableFrom(fieldType);
}

Merci, et s'il y a un moyen plus facile de tout peupler s'il vous plaît faites le moi savoir.

0
LazerBanana