Factory Boy is an library for Node.js which provides factories for objects creation. It's highly inspired by the fabulous factory_girl library for Ruby on Rails.
It comes with support for :
- associations
- lazy attributes
- defining factory initialization and creation methods
npm install factory-boy
Factory = require('factory-boy')
Factory.define 'user', class: User, ->
@first_name = 'John'
@last_name = 'Smith'
@pin = (callback) -> callback(null, Math.floor(Math.random()*10000))
Factory.build 'user', (err, user) ->
console.log user
Factory.create 'user', (err, user) ->
console.log user
Factory Boy use initializeWith and createWith methods for building and creating factory objects :
initializeWith: (klass, attributes, callback) ->
callback(null, new klass(attributes))
createWith: (klass, attributes, callback) ->
klass.create(attributes, callback)
You can overwrite this methods on global level or per each factory :
# overwriting globally
Factory = require('factory-boy')
Factory.initializeWith = (klass, attributes, callback) ->
callback(null, new klass.build(attributes))
Factory.createWith = (klass, attributes, callback) ->
new klass.build(attributes).create(callback)
# overwriting per factory
Factory.define 'user', class: User, ->
@initializeWith = (klass, attributes, callback) ->
callback(null, klass.build(attributes))
@createWith = (klass, attributes, callback) ->
new klass.build(attributes).create(callback)
Attributes defined by functions are evaluated upon object intialization/creation. Lazy functions context are set to factory instance so it's possible to use already defined attributes.
Factory.define 'user', class: User, ->
@first_name = 'John'
@salt = (callback) ->
time = new Date()
callback(null, "#{first_name}#{time}")
Additionally lazy functions are evaluated in the defined order.
Factory.define 'user', class: User, ->
@number1 = (callback) -> callback(null, 10)
@number2 = (callback) -> callback(null, @number1 + 10)
Sequences can be used for creating record with unique attributes i.e. emails. They are creating lazy attribute for given field with iterator passed as first argument.
Factory.define 'user', class: User, ->
@sequence 'email', (n, callback) ->
callback(null, "test#{n}@example.com")
First variable in callback will be increment for each records, starting from value 1. Therefore creating user factories will return records with unique emails.
Factory.define 'user', class: User, ->
@first_name = 'John'
@association('profile')
Factory.define 'profile', class: Profile, ->
@avatar_url = 'http://example.com/img.png'
Factory.create 'user', (err, user) ->
console.log user.profile_id
When using associations you can pass field name as first parameter.
Factory.define 'user', class: User, ->
@first_name = 'John'
@association('user_profile_id', 'profile')
Also you can set values to associated factory.
Factory.define 'user', class: User, ->
@first_name = 'John'
@association('profile', avatar_url: 'http://example.com/img2.png')
By default Factory Boy will use id field from associated factory. This can be changed by passing factory options.
Factory.define 'user', class: User, ->
@first_name = 'John'
@association('profile', factory: {field: 'external_id'})
- Fork it
- Install dependencies
npm install
- Make your changes on branch and make sure all tests pass
npm test
- Submit your pull request !