Showing posts with label factory-girl. Show all posts
Showing posts with label factory-girl. Show all posts

Wednesday, February 10, 2010

Factory Girl has many associations gotcha

Suppose Post has many Items

class Post < ActiveRecord::Base
has_many :items
end

class Item < ActiveRecord::Base
belongs_to :post
end

When setting up data for tests using factory girl

Factory.define :item do
u.post {|p| p.association(:post)}
end

Don't do this!

@post.items << Factory(:item)

Factory will create an item with another post_id and this will not be automatically changed to @post.id. Instead do this.

Factory(:item, :post => @post)

Friday, February 5, 2010

Running Shoulda & Factory Girl in Rails 3

Rails 3 uses Bundler gem to handle gem dependencies. Encountered some problems with Shoulda and Factory Girl.

# Gemfile

group :test do
gem "shoulda"
gem "factory_girl"
end

Shoulda and Factory Girl macros are not loaded so I had to require the gems in test/test_helper.rb

# test/test_helper.rb

require 'shoulda'
require 'factory_girl'
Factory.definition_file_paths = [ File.join(Rails.root, 'test', 'factories') ]
Factory.find_definitions

Tuesday, September 8, 2009

Using a factory name that doesn't correspond to a model


# Model

class GradeScaleRange < ActiveRecord::Base
end

# Factory

# Normally case -> OK!
Factory.define :grade_scale_range do
end

# This will scream!
Factory.define :grade_scale_range_a do
end

# Correct it with class name
Factory.define :grade_scale_range_a, :class => 'grade_scale_range' do
end

# Although the below seems ok in documentation. It will spew "dup NilClass" error
Factory.define :grade_scale_range_a, :class => GradeScaleRange do
end

Friday, July 31, 2009

Make Faker work with Factory Girl

If you use the code below, faker will not churn out unique names

Factory.define :user do |u|
u.first_name Faker::Name.first_name
u.last_name Faker::Name.last_name
end

However putting curly braces around faker makes it work!

Factory.define :user do |u|
u.first_name { Faker::Name.first_name }
u.last_name { Faker::Name.last_name }
end

Thursday, July 30, 2009

Has many association in Factory Girl


Factory.define :user do |user|
user.name "My Name"
user.addresses {|addresses| [addresses.association(:address)]}
end

Seed data into development database using Bootstrapper and Factory Girl

There's only so much development an application using unit tests and cucumber before we need to fire up the application on the browser in development mode. Trouble is we've written so many associated models and there did not contain any data in development database.

So comes seeding of data into my development database. I could do one of the following:

- Manually do SQL insertions of records into database
- Manually create and save objects in "script/console"
- Setup rake task to create records
- Use migration to insert seed data
- Use a SystemSettings model to create objects
- Use plugins like Seed_Fu and object creations
- Use plugins like Seed_Fu and fixtures
- Use Bootstrapper plugin with Factory Girl

Since I'm already using Factory Girl heavily with shoulda and cucumber, it makes sense to use them for my database seeding.

Bootstrapper gives nice convenience methods like

rake db:bootstrap
rake db:bootstrap:reset

You can specify different environments (test, development, staging, production, etc.) and run seeding modularly within the db/bootstrap.rb file

Bootstrapper.for :development do |b|
b.truncate_tables :addresses
b.run :users

Factory(:us_address, :state => "ME")
Factory(:us_address, :state => "IL")
Factory(:us_address, :state => "CA")
end

Bootstrapper.for :production do |b|
end

Bootstrapper.for :test do |b|
end

Bootstrapper.for :staging do |b|
end

Bootstrapper.for :users do |b|
3.times{ Factory(:user) }
Factory(:user, :login => "admin",
:password => "sekret",
:password_confirmation => "sekret")
end

You can then specify the bootstrapping that you wanna make

rake db:bootstrap BOOTSTRAP=users
rake db:bootstrap RAILS_ENV=production
rake db:bootstrap BOOTSTRAP=users RAILS_ENV=production