factory for building JavaScript objects, mostly useful for setting up test data. Inspired by factory_girl


Rosie is a factory for building JavaScript objects, mostly useful for setting up test data. It is inspired by factory_girl.

Define your factory, giving it a name and optionally a constructor function (Game in this example):

Factory.define('game'/*, Game*/)
  .attr('is_over', false)
  .attr('created_at', function() { return new Date(); })
  .attr('random_seed', function() { return Math.random(); })
  // Default to two players. If players were given, fill in 
  // whatever attributes might be missing. 
  .attr('players', ['players'], function(players) {
    if (!players) { players = [{}, {}]; }
    return {
      return Factory.attributes('player', data);
  .sequence('name', function(i) { return 'player' + i; })
  // Define `position` to depend on `id`. 
  .attr('position', ['id'], function(id) {
    var positions = ['pitcher', '1st base', '2nd base', '3rd base'];
    return positions[id % positions.length];
Factory.define('disabled-player').extend('player').attr('state', 'disabled')

Now you can build an object, passing in attributes that you want to override:

var game ='game', {is_over:true});

Which returns an object that looks roughly like:

    id:           1,
    is_over:      true,   // overriden when building 
    created_at:   Fri Apr 15 2011 12:02:25 GMT-0400 (EDT),
    random_seed:  0.8999513240996748,
    players: [
                {id: 1, name:'Player 1'},
                {id: 2, name:'Player 2'}

For a factory with a constructor, if you want just the attributes:

Factory.attributes('game') // return just the attributes 

You can also define a callback function to be run after building an object:

  .option('buildPlayer', false)
  .attr('players', ['id', 'buildPlayer'], function(idbuildPlayer) {
    if (buildPlayer) {
      return ['player', {coach_id: id})];
  .after(function(coachoptions) {
    if (options.buildPlayer) {
      console.log('built player:', coach.players[0]);
  });'coach', {}, {buildPlayer: true});

To use Rosie in node, you'll need to require it first:

var Factory = require('rosie').Factory;

You might also choose to use unregistered factories, as it fits better with node's module pattern:

// factories/game.js 
var Factory = require('rosie').Factory;
module.exports = new Factory()
  .attr('is_over', false)
  // etc 

To use the unregistered Game factory defined above:

var Game = require('./factories/game');
var game ={is_over: true});

Unregistered factories are even more natural in ES6:

// factories/game.js 
import { Factory } from 'rosie';
export default new Factory()
  .attr('is_over', false)
  // etc 
// index.js 
import Game from './factories/game');
const game ={is_over: true});

A tool like babel is currently required to use this syntax.

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Install the test dependencies (script/bootstrap - requires NodeJS and npm)
  4. Make your changes and make sure the tests pass (npm test)
  5. Commit your changes (git commit -am 'Added some feature')
  6. Push to the branch (git push origin my-new-feature)
  7. Create new Pull Request

Thanks to Daniel Morrison for the name and Jon Hoyt for inspiration and brainstorming the idea.