Skip to content

Randomization parameters

Mahmoud Ben Hassine edited this page Mar 20, 2021 · 21 revisions

The EasyRandomParameters is the main entry point to set all parameters of how to generate values:

EasyRandomParameters parameters = new EasyRandomParameters()
   .seed(123L)
   .objectPoolSize(100)
   .randomizationDepth(3)
   .charset(forName("UTF-8"))
   .timeRange(nine, five)
   .dateRange(today, tomorrow)
   .stringLengthRange(5, 50)
   .collectionSizeRange(1, 10)
   .scanClasspathForConcreteTypes(true)
   .overrideDefaultInitialization(false)
   .ignoreRandomizationErrors(true)
   .bypassSetters(true);

These parameters will be applied to all fields of the object graph.

Collection size range

The collectionSizeRange parameter lets you bound the generated collections size.

String length range

Setting the stringLengthRange parameter tells Easy Random to generate random strings with a bounded size.

Setting the Charset parameter

You can use the charset parameter to generate random values from the specified Charset in all character-based fields, basically strings and characters. This parameter will be applied to all String and Character fields in the object graph.

Bounded Date and Time values

You can use the dateRange and timeRange parameters to generate Date and Time values in a given range.

Setting the seed parameter

EasyRandom can be configured with a seed in order to generate the same random instances.

Using the same seed, each run will produce the same value. This feature is useful when you want stable random values across JVM restarts (for repeatable tests for instance).

Classpath Scanning

When the target object declares a field of an abstract or interface type, Easy Random will throw an ObjectGenerationException saying that it was unable to create a random instance of the abstract/interface type. The scanClasspathForConcreteTypes parameter tells Easy Random to scan the classpath and look for a concrete type of the abstract/interface field. Let's see a quick example:

abstract class Bar {}

class ConcreteBar extends Bar {}

class Foo {
   private Bar bar;
}

Let's try to generate a random instance of type Foo:

EasyRandomParameters parameters = new EasyRandomParameters().scanClasspathForConcreteTypes(true);
EasyRandom easyRandom = new EasyRandom(parameters);
Foo foo = easyRandom.nextObject(Foo.class);

In the generated Foo instance, the bar field will be assigned a random instance of the ConcreteBar type. Without setting the scanClasspathForConcreteTypes parameter, Easy Random will throw an ObjectGenerationException

Heads up: Please note that Easy Random will be in best effort mode when this parameter is activated. If a concrete type is found in the classpath, it is not guaranteed that Easy Random will be able to randomize it, in which case it will still throw an exception. In this case, you need to provide a custom randomizer for the abstract/interface type.

Override default initialization

By default, Easy Random does not randomise fields that are already initialized:

public class Bean {
   Set<String> strings = new HashSet<>();
   List<Integer> integers = Arrays.asList(1, 2, 3);

   public BeanWithDefaultValues() {
      
   }
}

If you randomize an instance of this Bean class, the strings field will be empty, and the integers fields will be equal to the list containing 1, 2 and 3. If you want to override this default initialization and randomize these fields, you need to set the overrideDefaultInitialization parameter.

Object pool size

When a type declares a field of the same type, Easy Random will not be able to generate a random object graph due to infinite recursion. Here is an example:

class Person {
   private String name;
   private Person parent;
}

To avoid infinite recursion, Easy Random provides the objectPoolSize parameter. This parameter limits the number of objects generated and acts a cache (but is not a real cache like ehcache or memcached). By default, the size of the object pool is equal to 10. This means in the previous example, Easy Random will generate at most 10 objects of type Person. After that, it will reuse the same objects from the pool for any field of type Person in the object graph. This parameter can also improve the performance of the randomization process for large object graphs.

Heads up: If you want to always generate distinct objects, you need to set the object pool size to a sufficiently large value. Obviously, this is only possible up to a certain limit (which is the objectPoolSize value), after which objects will be fetched from the pool to avoid the initial infinite recursion problem.

Randomization Depth

The randomizationDepth allows you to limit the randomization depth in an object graph. For example, if you have the following classes:

class A {
   private B b;
}

class B {
   private C c;
}

If you randomize an instance of type A with randomizationDepth = 2, the c field in the generated B instance will be null, that is, only the first 2 levels of the object graph are randomized.

Randomization Errors

By default, when Easy Random is not able to randomize a field or type, it will throw a ObjectGenerationException. If you want to silently ignore randomization errors, you can set the ignoreRandomizationErrors parameter. With this parameter set, any exception raised during the randomization process will be silently ignored and the corresponding field will be set to null.

Bypassing setters

This flag allows you to bypass setters (if any) and use reflection directly instead. False by default.