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
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
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.
Sequences are also evaluated in the defined order.
Factory.define 'user', class: User, ->
@number1 = (callback) -> callback(null, 10)
@number2 = (callback) -> callback(null, @number1 + 10)
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 !