Random values generation for testing purposes
Random values generation
The most basic value generation requires only passing the value type to the
Generators.randomValue() method:
String value = Generators.randomValue(String.class);
assertNotNull(value);
If null values are acceptable call Generators.nullableRandomValue() method:
String value = Generators.nullableRandomValue(String.class);
// The generated value can be null or a random value
Parameterized values generation
Generators can support optional generation parameters implementing the
dev.orne.test.rnd.params.ParameterizableGenerator interface.
This allows fine-tuning the generated values:
String value = Generators.randomValue(
String.class,
GenerationParameters.forNullables().withNullable(false),
GenerationParameters.forSizes().withMinSize(10));
Current built-in generation parameters:
| Type | Supported parameters types | Required parameters types |
|---|---|---|
| java.lang.CharSequence | Nullable, Size | |
| java.lang.String | Nullable, Size | |
| java.lang.Collection | Nullable, Size | SimpleGenerics |
| java.lang.List | Nullable, Size | SimpleGenerics |
| java.lang.Set | Nullable, Size | SimpleGenerics |
| java.lang.Map | Nullable, Size | KeyValueGenerics |
Collections generation requires, at least, the generic types parameters to success:
List<String> list = Generators.randomValue(
List.class,
GenerationParameters.forSimpleGenerics().withElementsType(String.class));
Map<String, Locale> map = Generators.randomValue(
Map.class,
GenerationParameters.forKeyValueGenerics()
.withKeysType(String.class)
.withValuesType(Locale.class),
GenerationParameters.forSizes().withMaxSize(5));
Map<String, Map<Integer, String>> nestedMap = Generators.randomValue(
Map.class,
GenerationParameters.forKeyValueGenerics()
.withKeysType(String.class)
.withValuesType(TypeUtils.parameterize(Map.class, Integer.class, String.class)),
GenerationParameters.forSizes().withMaxSize(5));
Targeted value generation
Targeted generators are generator instances that generate values for a target usage. Generators targeting bean properties, constructor parameters, method parameters and method return types are supported.
When a targeted generator generates values of a type whose registered generator
is a parameterizable generator uses the runtime information of the target to
populate the generation parameters. Currently the runtime ParameterizedType
of the target and following validation constraints are supported:
javax.validation.constraints.NotNulljavax.validation.constraints.Sizejavax.validation.constraints.Minjavax.validation.constraints.Maxjavax.validation.constraints.PositiveOrZerojavax.validation.constraints.Positive
Examples:
// Property
TargetedGenerator<String> generator = Generators.forProperty(
TestType.class,
"name")
String value = generator.randomValue(MyValidationGroup.class);
// Constructor parameter
TargetedGenerator<String> generator = Generators.forParameter(
MyBean.class,
new Class<?>[] { String.class },
0)
String value = generator.randomValue(MyValidationGroup.class);
// Method parameter
TargetedGenerator<String> generator = Generators.forParameter(
MyBean.class,
"myMethod",
new Class<?>[] { String.class },
0)
String value = generator.randomValue(MyValidationGroup.class);
// Method return type
TargetedGenerator<String> generator = Generators.forReturnType(
MyBean.class,
"myMethod",
new Class<?>[] { String.class })
String value = generator.randomValue(MyValidationGroup.class);
Annotation based random values generation in JUnit 5 tests
The library provides a JUnit 5 extension to inject random values based in
targeted value generation system. Add the @Random annotation to any field,
constructor parameter, test life-cycle callback parameter, or test method
parameter.
See targeted value generation and parameterized values generation for supported generation parameters extraction.
class MyTest {
// Generated on @BeforeAll phase
private static @Random Year staticNullableValue;
// Generated on @BeforeAll phase
private static @Random @NotNull Year staticNonNullValue;
// Generated once per @BeforeEach phase
private @Random Year instanceNullableValue;
// Generated once per @BeforeEach phase
private @Random @NotNull Year instanceNonNullValue;
@BeforeAll
static void beforeAllCallback(
// Generated on invocation
@Random String nullableValue,
@Random @NotNull String nonNullValue) {
assertNotNull(nonNullValue);
assertNotNull(staticNonNullValue);
}
@AfterAll
static void afterAllCallback(
// Generated on invocation
@Random String nullableValue,
@Random @NotNull String nonNullValue) {
assertNotNull(nonNullValue);
}
@BeforeEach
void beforeEachCallback(
// Generated on invocation
@Random String nullableValue,
@Random @NotNull String nonNullValue) {
assertNotNull(nonNullValue);
assertNotNull(instanceNonNullValue);
}
@AfterEach
void afterEachCallback(
// Generated on invocation
@Random String nullableValue,
@Random @NotNull String nonNullValue) {
assertNotNull(nonNullValue);
instanceValue = null;
}
RandomValueExtensionTest(
// Generated on class instantation
@Random String nullableValue,
@Random @NotNull String nonNullValue) {
assertNotNull(nonNullValue);
}
@Test
void testSomething(
// Generated once per invocation
@Random String nullableValue,
@Random @NotNull String nonNullValue) {
assertNotNull(nonNullValue);
}
}
Supported out-of-the-box types
- Primitives and wrapper types
java.lang.Booleanjava.lang.Bytejava.lang.Shortjava.lang.Integerjava.lang.Longjava.lang.Floatjava.lang.Doublejava.lang.Character
- Common JRE types
java.lang.CharSequencejava.lang.Numberjava.lang.Stringjava.io.Filejava.math.BigIntegerjava.math.BigDecimaljava.nio.charset.Charsetjava.nio.file.Pathjava.util.Calendarjava.util.Currencyjava.util.Datejava.util.Localejava.util.TimeZonejava.util.URIjava.util.URLjava.util.UUIDjava.time.Clockjava.time.Durationjava.time.Instantjava.time.LocalDatejava.time.LocalDateTimejava.time.LocalTimejava.time.MonthDayjava.time.OffsetDateTimejava.time.OffsetTimejava.time.Periodjava.time.Yearjava.time.YearMonthjava.time.ZonedDateTimejava.time.ZoneIdjava.time.ZoneOffsetjava.time.chrono.Chronology
- Arrays and collections
java.lang.Arrayjava.util.Collectionjava.util.Listjava.util.Setjava.util.Map
- Enumerations
- Annotated beans
- Annotated constructor based bean generator
- Annotated method based bean generator
Generic beans generation
Not every bean type requires a dedicated generator. For simple bean types annotation based generation is supported.
Annotated constructor based bean generation
Beans with a constructor annotated with @GeneratorMethod will be generated
out-of-the-box calling the annotated constructor with targeted random arguments:
public class MyType {
@GeneratorMethod
public MyType(
Integer paramA,
String paramB) {
super();
// Populate bean
}
}
Annotated method based bean generation
Alternatively, beans can annotate a factory method with @GeneratorMethod will
be generated out-of-the-box calling the annotated method with targeted random
arguments:
public class MyType {
@GeneratorMethod
public static @NotNull MyType factory(
Integer paramA,
String paramB) {
MyType bean = new MyType();
// Populate bean
return bean;
}
}
