README
objection-factory
This library allows you to define factories for your Objection.js models. You can use it to generate dummy records for your unit and integration tests. Data is generated via faker.js.
Contents
Installation
You can install this package via npm:
npm install objection-factory
Usage
const { Model } = require('objection');
// 1. Import objection-factory
const Factory = require('objection-factory');
// 2. Define your model
class User extends Factory(Model) {
// ...
// 3. Define the factory schema
static get factorySchema() {
return {
// `faker` is an instance of the faker.js library
firstName: this.faker.name.firstName,
lastName: this.faker.name.lastName,
email: this.faker.internet.email,
};
}
}
// 5. Use the model factory in your unit tests!
const users = await User.create({ count: 50 });
//... assertions ...
await User.cleanup();
API
This library provides a class that your models must extend in order to enable factories.
const { Model } = require('objection');
const Factory = require('objection-factory');
class User extends Factory(Model) {
// ...
}
Below, you can find a list of methods and attributes provided by the class.
static get factorySchema
It provides the schema used for generating dummy objects. It expects to return an object where each key is a valid column name, and each field is either a faker.js method, a function, or a literal. Note that the faker
attribute is already included in the library's class.
Example
static get factorySchema() {
return {
firstName: this.faker.name.firstName,
lastName: this.faker.name.lastName,
email: this.faker.internet.email,
};
}
static make(options = {})
Generates one or multiple JavaScript objects in accordance with the schema specified via factorySchema
. You can turn the object into a model by using fromJson
.
Options
count
:Number
(default:1
)The amount of dummy objects that must be generated.
override
:Object?|Array?
(default:null
)It provides defaults to override the generated data. It expects an object when
count
is set to1
, otherwise it expects an array of objects. If the length of the array is less thancount
, only some of the dummy objects—starting from the first one—will be overridden.
Returns
An object if count
is set to 1
, otherwise it returns an array of objects.
Example
const user = User.make();
const users = User.make({ count: 3 });
const ivy = User.make({
count: 1,
override: { firstName: 'Ivy' },
});
// Overrides only the names of the first two objects
const johnAndJoe = User.make({
count: 5,
override: [
{ firstName: 'John' },
{ firstName: 'Joe' },
],
});
static async create(options = {})
Generates one or multiple models, and writes them to the database, in accordance with the schema specified via factorySchema
. You can turn the model into an object by using toJSON
.
Options
count
:Number
(default:1
)The amount of dummy objects that must be generated, and written to the DB.
batch
:Boolean
(default:false
)Indicates whether we must optimize the batch insert. It does NOT preserve the order in which you passed the records. If you don't enable this flag for a batch insert, it'll be unoptimized but the order will be preserved.
override
:Object?|Array?
(default:null
)It provides defaults to override the generated data. It expects an object when
count
is set to1
, otherwise it expects an array of objects. If the length of the array is less thancount
, only some of the dummy objects—starting from the first one—will be overridden.resolveRelationships
:Boolean
(default:false
)See Relationships.
Returns
An instance of your model if count
is set to 1
, otherwise it returns an array of models.
Developer's Notes
The method reverts all the inserts, even the successful ones, when one of them fails. At the moment, you can't customize this behaviour.
Example
const users = await User.create({ count: 3 });
console.log(users[0] instanceof User); // true
console.log(isNaN(user[1].id)); // false
static async cleanup()
Removes all the records that have been inserted via create
.
Example
await User.create({ count: 300 });
await User.cleanup();
Relationships
The create
methods supports both belongs to and has many relationships.
Each relationship must be defined in the relationMappings
object of your model (see Objection.js' documentation). You must always specify the join
property, and join.to
must always point to the modelClass
model.
// ...
user: {
modelClass: User,
relation: Model.BelongsToOneRelation,
join: {
from: `${this.tableName}.userId`,
to: `${User.tableName}.${User.idColumn}`,
},
}
// ...
You can manually specify how to resolve relationships—see the next sections—or you can let the library resolve relationships for you. You can also combine these two options.
// Automatically resolve relationships
const parentPost = await Post.create({
resolveRelationships: true,
});
// Automatically resolve all relationships but `parent`
const posts = await Post.create({
count: 3,
resolveRelationships: true,
belongsTo: {
parent: parentPost,
},
})
Belongs to relationships
The create
method accepts a belongsTo
object, where each key is a relationship name—defined in relationMappings
object of your model—and each value is an array with two elements:
- a literal (string or number), a model definition, or an instance of a model.
- an object containing configuration options:
clear
(default:false
): indicates whethercleanup
must remove the record associated to the relationship
If you don't need configuration options, you can skip the array.
const parentPost = await Post.create({
resolveRelationships: true,
});
const posts = await Post.create({
count: 3,
belongsTo: {
form: [Form, { clear: true }],
user: [user, { clear: true }],
// `parentPost` must be removed manually
parent: parentPost,
},
})
Has many relationships
[...]
License
objection-factory is released under the MIT License.