switching from fixtures to Factory Girl-Collection of common programming errors

Rails 3.0.3….

I’m just starting out with Factory Girl, having had little success with the standard fixtures approach. I’ve commented out fixtures :all from the test/test_helper.rb file and have created a factories file.

My problem is that the sequence feature doesn’t seem to work:

# test/factories.rb
Factory.sequence :clearer_name do |n|
   "Clearer_#{n}"
end

Factory.define :clearer do |f|
   f.name Factory.next(:clearer_name)
end

My (functional) test is only slightly different from standard:

require 'test_helper'

class ClearersControllerTest < ActionController::TestCase
   setup do
      @clearer = Factory.create(:clearer)
   end

test "should get index" do
   get :index
   assert_response :success
   assert_not_nil assigns(:clearers)
 end

 test "should get new" do
   get :new
   assert_response :success
 end

 test "should create clearer" do
   assert_difference('Clearer.count') do
     post :create, :clearer => @clearer.attributes
   end

   assert_redirected_to clearer_path(assigns(:clearer))
 end

When I run rake test I get:

test_should_create_clearer(ClearersControllerTest):
ActiveRecord::RecordNotUnique: SQLite3::ConstraintException: column name is not unique: INSERT INTO "clearers" ("active", "updated_at", "name", "created_at") VALUES ('t', '2011-02-20 08:53:37.040200', 'Clearer_1', '2011-02-20 08:53:37.040200')

…as if it’s not continuing the sequence.

Any tips?

Thanks,

UPDATE: heres my test file:

#clearers_controller_test.rb
require 'test_helper'
class ClearersControllerTest < ActionController::TestCase
  setup do
    @clearer = Factory.create(:clearer)
  end

  test "should create clearer" do

    assert_difference('Clearer.count') do
      # does not work without this:
      Clearer.destroy_all 
      post :create, :clearer => @clearer.attributes
    end
end

I can get this to work by putting Clearer.destroy_all at the top of the test method as shown, but that doesn’t feel right.

  1. I see – In your setup, you’re creating a Clearer instance. The Factory.create method builds and saves a new record and returns it.

    The problem is that you’re then attempting to create another instance in your “should create clearer” test but you’re re-using the existing instance’s attributes.

    If you want Factory to return fresh attributes (and the next name sequence), you need to ask it for new attributes:

    test "should create clearer" do
      assert_difference('Clearer.count') do
        post :create, :clearer => Factory.attributes_for(:clearer)
      end
    end
    

    You should only be using that existing @clearer instance in the context of an existing record, not where you want a new one.

  2. You aren’t starting with a fresh database is my guess. There’s lots of reasons this could be happen, but you can verify that’s the problem by adding a Clearer.destroy_all in your setup function, before creating one.