Blogger.create { :name =>'Matt Aimonetti',
:location => 'San Diego, Ca',
:email => mattaimonetti AT gmail.com,
:linkedin => Matt's Linkedin page,
:recommend_me => HERE,
:contractor => true}

db fixtures replacement solution step by step

Written by matt on September 7th, 2008

Like most people who started with Rails a while back, I first loved Rails fixtures and ended up hating them (slow, a pain to maintain etc...).

I went through different experiments, trying different existing libs, writing my own solutions etc... I wasn't quite satisfied until I found factory_girl from thoughtbot.

You might not feel the need for a decent fixtures solution if you do a lot of mocking/stubbing, but I recently came back from my "mock everything you can outside of models" approach and I'm getting closer to the mock roles, not objects approach. So, I'm loosing my model/controller testing separation but I'm gaining by not having to maintain "dumb mocks" which don't always represent the real API behind. I mean, how many times did I change a Model, messing up my app but all my specs were still passing. Anyway, that's a long discussion, which will be covered by wycats during merbcamp

So here is a simple example of how I use factory girl in a Merb + DataMapper app. (you can do the same in a Rails app, there is nothing specific to Merb in factory_girl).

  • I. create an empty app, set the ORM etc...

  • II. git pull and install factorygirl from http://github.com/thoughtbot/factorygirl/tree/master. Or install thoughtbot-factory_girl gem using GitHub gem server.

  • III. create a spec/factories.rb file. (You might prefer to create a folder called spec/factories and add a factory per model)

  • IV. modify spec_helper.rb and add the following

1
2
3

  require 'factory_girl'
  require File.dirname(__FILE__) + '/factories'
  • V. write some specs against a Client model
  • VI. Create the Model
  • VII. create a factory
  • IIX. run your specs

    failing specs

  • IX. fix the model (note that I set dependencies "dm-validations" in my init.rb)

  • X. run the specs

    passing specs

  • XI. add more specs

As you can see, Factory.build(:client) only creates a new instance of the Object, while Factory(:client) creates, saves and loads the instance.

  • XII. get them to pass

Factory Girl makes fixtures simple and clean. Here is another example for creating associations:

Factory Girl also supports sequencing, check out FG read me

In conclusion, Factory Girl is a mature and solid factory solution which will take you less than 15 minutes to get used to. It will offer you loads of flexibility and less frustration than good old yaml fixtures. You can also use it with existing fixtures if you want to start using it in an existing app.



Comments

  • Nicolas Mérouze on 07 Sep 10:34

    Why not to use merb-fixtures with merb? It looks like it's pretty much the same. (because factory_girl is one library which can be used everywhere ?)

  • Matt Aimonetti on 07 Sep 12:30

    @nicolas good question! So you have 2 alternatives quite popular in the Merb world:

    merb-fixtures and dm-sweatshop while both options are pretty good they are not framework/ORM agnostic.

    Also merb-fixtures doesn't auto save fixtures like when you do Factory(:client) instead of Factory.build(:client) and the declaration of associations is dodgy IMHO. (plus it has a limited API, no support for seques etc...)

    dm-sweatshop is better than merb-fixtures but only works with DM at the moment. (it used to be ORM agnostic) It has a great API and offers most of the sexiness from factory_girl.

  • Bryan Ray on 12 Sep 07:46

    Thanks for the write up, Matt.

    I typically used the object_daddy plugin in Rails and wasn't sure anything like this was out there for Merb.

    I'll be playing with factory_girl and dm-sweatshop this weekend.

  • grosser on 12 Sep 11:32

    a great deal of these tests can be simplified to something like

    assertinvalidattributes User, :login=>['',nil,'admin'], :email=>['',nil,'aa'] etc

    http://pragmatig.wordpress.com/2008/04/04/testing-validation-the-dry-way/

    especially the == "less than xx and more than yy" test semm very brittle to me, add one character and boom.. not very maintainable

Comments are closed