home icon contact icon rss icon

By: Matt Lins

Shoulda + Factory_Girl + Webrat for Rails Integration Tests

Is anyone else using shoulda, factory_girl and webrat for Rails integration tests?

I did a quick search and found Daniel Wellman using it in integration tests minus shoulda and factory_girl. I really like adding shoulda to get the contexts and factory_girl is a great replacement for fixtures. When combined with webrat it really makes for some easy to read integration tests. By the way, I'm already using shoulda and factory_girl for my unit and functional tests.

Here is an example I whipped up last night. It's nothing fancy. I'll probably make some modifications in the future, but so far I'm happy with it. I'm loading webrat in my test_helper.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
require '../test_helper'

class AdminLoginTest < ActionController::IntegrationTest
  context 'An employee' do
    setup do
      @employee = Factory(:employee)
    end

    should 'be able to login with a valid username and password' do
      visit '/admin'
      assert https?
      assert_equal '/admin/sessions/new', path
      fills_in 'Email', :with => @employee.user.email
      fills_in 'Password', :with => @employee.user.password
      clicks_button 'Log In'
      assert_equal @employee.user.id, session[:user_id]
    end

    should 'be denied access with an invalid username or password' do
      visit '/admin'
      assert https?
      assert_equal '/admin/sessions/new', path
      fills_in 'Email', :with => @employee.user.email
      fills_in 'Password', :with => 'wrongpassord'
      clicks_button 'Log In'
      assert_nil session[:user_id]
    end
  end
end

This is testing a simple login to the admin section of a project I'm working on. We're using restful_authentication. Each line of each test is essentially an assertion. If something doesn't respond with a success or a form field is missing, the test fails.

By: Matt Lins

Factory_Girl Sequences as Lazy Attributes

I just ran into a problem with factory_girl sequences. The problem was I defined my Factories like this:

1
2
3
4
5
6
7
8
9
10
11
12
# Sequences

Factory.sequence :name do |n|
  'name' + n.to_s
end

# Manufacturers

Factory.define :manufacturer do |m|
  m.name Factory.next(:name)
  m.active true
end

Assume I have a validates_uniqueness_of validation on name in Manufacturer:

1
2
3
4
5
class Manufacturer < ActiveRecord::Base

  validates_uniqueness_of :name

end

Now, lets say I created a couple of manufacturers in my test setup:

1
2
3
4
5
6
7
8
9
require File.dirname(__FILE__) + '/../test_helper'

class ProductTest < ActiveSupport::TestCase

  setup do
    2.times { Factory(:manufactuer) }
  end

end

Ok, this setup block will fail because it's creating 2 manufacturers with the same name. But, I thought I was using a sequence? Well, the sequence is only sequenced during the definition of the factories. Meaning, in the above example Factory#next was only called once.

Luckily, factory_girl allows us to use something called lazy attributes. We can just wrap our sequence with some curly brackets, like so:


m.name { Factory.next(:name) }

Now everytime I create a new Manufacturer the sequence will generate a unique name. Nice! Maybe if I'd taken some more time to RTFM, I wouldn't have wasted time on this problem. Regardless, I thought maybe I'd be able to help someone else out that runs into this.

More about factory_girl