Unique Marketing, Guaranteed Results.

Tutorial: How to install/setup RSpec (and Factory Girl) in Rails

April 3rd, 2009 by Alan Carl Mitchell

This tutorial assumes that you have ruby, rails, and mysql installed on your machine. This tutorial also doesn’t explain much about RSpec or Factory Girl and will just show you a quick way to get them working in a RoR environment.

Create the Rails Project
Go to your projects directory and create a rails project. Just for fun, let’s call it ‘bank’:

user@host:~$ cd projects
user@host:~/projects$ rails -d mysql bank
user@host:~/projects$ cd bank
user@host:~/projects/bank$

Create MySQL Databases
Go into mysql and create the two databases that rails has set up the bank project to use:

user@host:~/projects/bank$ mysql -u root -p
mysql>create database bank_development
mysql>create database bank_test
mysql>exit
Bye
user@host:~/projects/bank$

Put Gems Into Environments
Edit the files

config/environments/development.rb

and

config/environments/test.rb:

and add the following lines:

config.gem "thoughtbot-factory_girl", :lib => 'factory_girl', :source => 'http://gems.github.com'
config.gem "rspec", :version => '1.2.2', :lib => 'spec'
config.gem "rspec-rails", :version => '1.2.2', :lib => false

This sets up the test and development environments to use rspec and factory girl.

Install the Gems
Install the gems referenced in your environments:

user@host:~/projects/bank$ rake gems:install

You’ll see output that says that the gems were installed, if you didn’t have them already.

Bootstrap RSpec
Do a:

user@host:~/projects/bank$ script/generate rspec

You will see the following:

user@host:~/projects/bank$ script/generate rspec
exists lib/tasks
create lib/tasks/rspec.rake
create script/autospec
create script/spec
create script/spec_server
create spec
create spec/rcov.opts
create spec/spec.opts
create spec/spec_helper.rb
user@host:~/projects/bank$

This generates some default rspec files and directories that the project will use.

Generate Model, Test, and Migration with rspec_model
Do a:

user@host:~/projects/bank$ script/generate rspec_model BankAccount

You will see the following output:

user@host:~/projects/bank$ script/generate rspec_model BankAccount
exists app/models/
create spec/models/
create spec/fixtures/
create app/models/bank_account.rb
create spec/models/bank_account_spec.rb
create spec/fixtures/bank_accounts.yml
create db/migrate
create db/migrate/20090402160952_create_bank_accounts.rb
user@host:~/projects/bank$

This will create a default test at

spec/models/bank_account_spec.rb

and a BankAccount model in

app/models/bank_account.rb

and a migration in

db/migrate/20090402160952_create_bank_accounts.rb

You can also do a script/generate rspec_scaffold BankAccount.

Edit the Test
Go to

spec/models/bank_account_spec.rb

and you will see:

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
 
describe BankAccount do
  before(:each) do
    @valid_attributes = {
    }
  end
 
  it "should create a new instance given valid attributes" do
    BankAccount.create!(@valid_attributes)
  end
end

Since this is a bank account, one of the behaviors that we would expect is to be able to make deposits into it. That being the case, let’s change the test to

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
 
describe BankAccount do
  before(:each) do
    @bank_account = BankAccount.create
    @bank_account.balance = 0
  end
 
  it "should increase the balance upon deposit" do
    @bank_account.deposit(100)
    @bank_account.balance.should == 100
  end
end

Also, edit

spec/spec.opts

and change ‘progress’ to ‘specdoc’ (because it will make rspec output look a lot better)

Edit the Migration
We need to add the ‘balance’ attribute to the model. Go to

db/migrate/20090402160952_create_bank_accounts

(or some file like that)

and change the migration to

class CreateBankAccounts < ActiveRecord::Migration
  def self.up
    create_table :bank_accounts do |t|
      t.float :balance
 
      t.timestamps
    end
  end
 
  def self.down
    drop_table :bank_accounts
  end
end

Edit the Model Now we need to add the deposit method to the BankAccount model. Go to

app/models/bank_account.rb

Change the class to

class BankAccount < ActiveRecord::Base
 
  def deposit(amount)
    self.balance = self.balance + amount
  end
 
end

Migrate the DB, Run RSpec Now, do a

user@host:~/projects/bank$ rake db:migrate

and then a

user@host:~/projects/bank$ rake spec

You should see:

user@host:~/projects/bank$ rake spec
(in /home/osadmin/projects/bank_account/bank)

BankAccount
- should increase the balance upon deposit

Finished in 0.066398 seconds

1 example, 0 failures
user@host:~/projects/bank$

At this point, RSpec is functioning.

Add Factory Girl
Want to add Factory Girl? The environments are already set up and gem is installed. The rest is not hard:

Create a ‘factories’ directory under the ‘spec’ directory.

user@host:~/projects/bank$ mkdir spec/factories
user@host:~/projects/bank$

and make the file

spec/factories/bank_accounts.rb

and put this inside:

Factory.define :bank_account do |ba|
  ba.add_attribute :balance, 0
end

Edit the Test
Open

spec/models/bank_account_spec.rb

Change the body of the before each block to

@bank_account = Factory(:bank_account, :balance => 0)

Since the factory you just made (spec/factories/bank_accounts.rb) automatically sets the balance to 0, you could leave the body with just

@bank_account = Factory(:bank_account)

and it would still work.

The finished spec/models/bank_account_spec.rb will look like this:

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
 
describe BankAccount do
  before(:each) do
    @bank_account = Factory(:bank_account, :balance => 0)
  end
 
  it "should increase the balance upon deposit" do
    @bank_account.deposit(100)
    @bank_account.balance.should == 100
  end
end

Watch RSpec Run With Factory Girl
Watch the test run with Factory Girl:

user@host:~/projects/bank$ rake spec
(in /home/osadmin/projects/bank_account/bank)

BankAccount
- should increase the balance upon deposit

Finished in 0.066398 seconds

1 example, 0 failures
user@host:~/projects/bank$

Be Sociable, Share!
Filed under: Design,Programming — Tags: , , , — Alan Carl Mitchell @ 3:04 pm on April 3, 2009

4 Comments

  1. [...] Cucumber and will mostly show you a quick way to get it working. A lot of material is borrowed from this tutorial on setting up RSpec and Factory Girl. It may be useful to look over first, but not [...]

    Pingback by How to Install Cucumber | PMA Media Group — April 9, 2009 @ 10:32 am

  2. getting error when installing rspec

    Comment by gayu — May 30, 2009 @ 12:31 am

  3. And moreover, in addition to that, we can enhance factories with their own helper methods. To design clean and complicated factories – http://conceptspace.wikidot.com/blog:39

    Factory.define :child do |f|

    class << f
    #do whatever you can do in a normal class definition
    def default_parent
    @default_parent ||= Factory(:parent)
    end
    end

    f.sequence(:name) {|n| "Child#{n}"}
    f.parent_id { f.default_parent.id }
    end

    Comment by Umuro — June 25, 2009 @ 7:54 am

  4. very good stuff….thank you

    Comment by sharma — March 20, 2011 @ 9:53 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

Copyright © 2005-2014 PMA Media Group. All Rights Reserved