@apusart/test-data-generator
v1.0.8
Published
TestDataGenerator is a modest npm package tailored to assist TypeScript developers in effortlessly generating test data using annotations. By simply annotating class properties, developers can establish rules for generating mock data, simplifying the test
Downloads
26
Maintainers
Readme
Installation
To install TestDataAnnotations, simply run:
npm install --save-dev test-data-annotations
Usage
Using TestDataAnnotations is straightforward. Simply annotate your class properties with decorators to define rules for generating mock data.
import { GenUuid, GenArray, ModelFactoryBuilder, UserFactory } from '@apusart/test-data-annotations';
class User {
@GenUuid()
id: string;
}
const UserFactory = ModelFactoryBuilder.create(User).build();
const user: User = UserFactory.create();
Test data definition
Overview
The test-data-annotations library provides decorators to facilitate the generation of test data for TypeScript classes. These decorators can be applied to class properties to specify how they should be populated with test data.
Example
Consider the following example class:
import { GenUuid, GenArray } from '@apusart/test-data-annotations';
class User {
@GenUuid()
id: string;
@GenString()
name: string;
@GenNumber({ type: "int", options: { min: 1, max: 80 } })
age: number;
@GenArray(5)
@GenString()
roles: string[];
}
In this example:
id
property is annotated with@GenUuid()
, indicating that it should be populated with UUID.name
property is annotated withGenString
, which by default is alphanumerical string.age
property is annotated with@GenNumber()
, specifying the type as int and options to populate this field with integers from the range 1 to 80.- The
roles
property is annotated with@GenArray()
and@GenString()
, indicating that it should be populated with an array of 5 strings.
Available Annotations
These annotations are strongly based on the type generation capabilities provided by faker.js.
| Annotation | Description | Defaults
|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --------------------- |
| @GenArray(length?)
| Generates an array for the annotated property. The length
parameter specifies the number of elements in the array. It requires annotation declaring the type. | 1
| @GenBoolean()
| Generates a boolean | -
| @GenEnum(enum)
| Generates value of provided enum | any
| @GenEmail(options?)
| Generates email | { firstName?: "string", lastName?: "string", provider: "string" }
| @GenNumber(options?)
| Generates a number for the annotated property. Options can specify the type (e.g., int
, float
) and define the range of values. | { type: "int", options: undefined }
| @GenString(options?)
| Generates a string for the annotated property. By default, it generates an alphanumerical string. Options can customize the generated string, such as length or format. | { type: "alphabetical", options: undefined }
| @GenType(type)
| Generates instance of a type provided as parameter | T extends object
| @GenUuid()
| Generates a UUID (Universally Unique Identifier) for the annotated property. | -
GenProperty Helper Function:
In cases where the predefined annotations are not sufficient for your needs, the GenProperty helper function can be used. This function allows you to define custom generators for your properties using faker.js methods directly or your custom logic. By utilizing GenProperty, you can generate test data tailored to your specific requirements beyond the scope of the provided annotations. GenProperty helper function can be used like this:
function GenYourType() {
return GenProperty({
generationFn: () => {
// Your generation logic here
return "Your generated value";
}
});
}
Creating factory
Factories are a core feature of the test-data-annotations library, enabling the generation of instances for annotated classes with randomized data aligned to specified annotations. By defining a factory for your class, you can effortlessly generate mock instances, ensuring your application behaves as expected across diverse scenarios. Factories streamline the test data generation process, saving time and effort in your development workflow.
To create a type factory, utilize the ModelFactoryBuilder. Instantiate the ModelFactoryBuilder by invoking its create method and specifying the type you wish to randomize. Additionally, the ModelFactoryBuilder offers useful methods:
- withInput: This method allows you to manipulate generated value with input from the outside. This function is taking two arguments: the generated random type and any desired input (e.g., string, number, or object). The input function must return the same type provided in the create function. If no input is provided, it won't be accessible later in the factory itself.
const TodoFactory = ModelFactoryBuilder.create(Todo) .withInput((todo: Todo, user: User) => ({ // allows specifying additional data ...todo, userId: user.id, })) .build();
- build: creates factory.
Using factory
A factory, integral to the test-data-annotations library, serves as a crucial tool for generating instances of annotated classes with randomized data according to specified annotations and configurations set in the builder. Once defined, a factory acts as a blueprint for creating mock instances tailored to your class structure and annotation configurations.
The factory also functions as a builder, allowing you to specify input and override objects before invoking the create()
function.
Create Function
The create()
function takes only one argument: a number specifying the quantity of instances to generate, defaulting to 1. If you specify more than one instance, you also need to provide the same amount of input and override when used.
const user: User = UserFactory.create();
const [user1, user2] = UserFactory.create(2);
Input Function
The input function allows you to manipulate data with the provided function in the ModelFactoryBuilder. Input becomes particularly useful when properties of the generated type rely on other types not included in Partial<T>
, as it is in override.
const user: User = UserFactory.create();
const todo: Todo = TodoFactory.input(user).create(); // if you don't specify input function this will throw compile error
const [todo1, todo2] = TodoFactory.input([user, user]).create(2); // if you don't specify input function this will throw compile error
Override Function The override function replaces the generated type with the provided partial object as an argument.
const user: User = UserFactory.create();
const todo: Todo = TodoFactory.override({ userId: user.id }).create();
const [todo1, todo2] = TodoFactory.override([
{ userId: user.id },
{ id: uuid() },
]).create();
IMPORTANT! The input function is called before the override function.
Contributing
Contributions are welcome! If you encounter any issues or have suggestions for improvements, please feel free to open an issue or submit a pull request.
License
TestDataAnnotations is licensed under the MIT License. See the LICENSE file for details.