Generation

OBJECTO

Objecto provides multiple annotations for customization, allowing developers to tailor the generation process.

@Generator

The @Generator annotation is utilized to specify a generation strategy for an object's type or particular attribute.

This annotation allows developers to define complex expressions to determine the attribute that should be generated. The expression attribute within the annotation supports a variety of scenarios, providing flexibility for different use cases.

  • Simple Field Name: Use a single field name like "key"

  • Path to Nested Field: Navigate through nested fields, for instance, "property.value"

  • Array or List Indexing: Utilize array or list indexing, such as "properties[*].value"

  • Method Invocation: Invoke methods with the result of the generator passed as a parameter, as demonstrated in "properties.setSize(?)"

  • Parameters: Generator methods can be defined without parameters or with a single parameter. When a parameter is used, it can be either of type java.util.Random or com.cariochi.objecto.utils.ObjectoRandom. Objecto invokes these methods during generation, providing the current Random or ObjectoRandom instance with the set seed value. This enables developers to use these random instances for custom generation, ensuring that generated values are consistent and repeatable when a seed is specified.

Example:

// Custom type generation
@Generator
private String generateString(Random random) {
    return new Faker(random).lorem().sentence();
}

// Custom field generation
@Generator(type = Issue.class, expression = "key")
private String generateIssueKey(ObjectoRandom random) {
    return "ID-" + random.nextInt(Range.of(1000, 10000));
}

@Generator(type = Issue.class, expression = "attributes[*].value")
private String generateIssueAttributeValues(Random random) {
    return new Faker(random).lorem().word();
}

@Generator(type = Issue.class, expression = "attributes.setSize(?)")
private int generateIssueAttributesSize() {
    return 101;
}

@Instantiator

Use @Instantiator annotation to specify methods for creating instances of certain types.

Example:

@Instantiator
private Attachment<?> newAttachment() {
    return Attachment.builder().fileContent(new byte[0]).build();
}

@PostProcessor

User @PostProcessor annotation to specify a post-processing step for generated instances.

Example:

@PostProcessor
private void userPostProcessor(User user) {
    String username = user.getFullName().toLowerCase().replace(".", "").replace(" ", ".");
    user.setUsername(username);
    user.setEmail(username + "@" + new Faker().internet().domainName());
}

@References

The @References annotation plays a crucial role in managing relationships between entities, especially in the context of generating random objects with correct associations. This annotation is particularly useful for ensuring the proper establishment of bidirectional links and managing complex inter-entity connections during random object generation.

The primary use case for @References is to guide the random object generation process, preventing the unnecessary creation of new objects for certain fields. Instead, it ensures that already generated objects are correctly referenced, maintaining consistency in bidirectional relationships.

Examples:

public interface BaseIssueFactory {

    @References("subtasks[*].parent")
    Issue createIssue(); 
}

public interface CourseFactory {

    @References({"professor.assignments[*].course", "enrollments[*].course"})
    Course createCourse();

    @References("enrollments[*].student")
    Student createStudent();   
}

@WithSettings

The @WithSettings annotation is a versatile configuration annotation designed to modify default settings for object generation. This annotation can be applied both globally, influencing the entire factory, and locally to fine-tune the generation of specific fields within the generated objects.

@WithSettings Attributes:

SettingDescriptionDefault Value

maxDepth

Maximum depth for the object graph.

4

maxRecursionDepth

Maximum recursion depth for cyclic references.

2

longs

Range for generating long values.

min = 1

max = 100 000

integers

Range for generating int values.

min = 1

max = 100 000

bytes

Range for generating byte values.

min = 65

max = 91

bigDecimals

Configuration for generating BigDecimal instances.

doubles

Range for generating double values.

min = 1

max = 100 000

floats

Range for generating float values.

min = 1

max = 100 000

years

Range of years relative to the current year.

min = -5

max = 1

collections

Configuration for generating collections.

arrays

Configuration for generating arrays.

maps

Configuration for generating maps.

strings

Configuration for generating strings.

@Strings Attributes:

SettingDescriptionDefault Value

size

Size range for generating strings.

min = 8

max = 16

uppercase

Whether generated strings should be in uppercase.

true

type

Type of characters to include in generated strings.

Options:

  • ALPHABETIC - Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z)

  • ALPHANUMERIC - Characters will be chosen from the set of Latin alphabetic characters (a-z, A-Z) and the digits 0-9

  • ASCII - Characters will be chosen from the set of characters whose ASCII value is between 32 and 126 (inclusive)

  • NUMERIC - Characters will be chosen from the set of \p{Digit} characters

  • GRAPH - Characters will be chosen from the set of \p{Graph} characters

  • PRINT - Characters will be chosen from the set of \p{Print} characters

ALPHABETIC

fieldNamePrefix

Whether to include a field name prefix in generated strings.

false

@Collections Attributes:

SettingDescriptionDefault Value

size

Size range for generating collections.

min = 2

max = 5

@BigDecimals Attributes:

SettingDescriptionDefault Value

min

Minimum value for generating BigDecimal instances.

0

max

Maximum value for generating BigDecimal instances.

100_000.0

scale

Scale for generating BigDecimal instances.

4

@IntRange, @LongRange, @DoubleRange, and @FloatRange Attributes:

SettingDescription

min

Minimum value for generating the respective type.

max

Maximum value for generating the respective type.

Example:

@WithSettings(strings = @Strings(fieldNamePrefix = true))
interface DtoFactory {

    @WithSettings(path = "month", integers = @IntRange(min = 0, max = 12))
    @WithSettings(path = "year", integers = @IntRange(min = 2000, max = 2025))
    Dto createDto();

}

Last updated