Rails 3 + Rspec 2: Validation failed: Email has already been taken
Asked Answered
C

3

8

I have 2 models, User and Bucket. User has_many Buckets and a Bucket belongs_to a User.

In factories.rb, I have:

Factory.define :user do |user|
  user.email  "[email protected]"
  user.password               "foobar"
  user.password_confirmation  "foobar"
end


Factory.sequence :email do |n| 
  "person-#{n}@example.com"
end

Factory.define :bucket do |bucket|
  bucket.email        "[email protected]"
  bucket.confirmation false
  bucket.association :user
end

and I have a login_user module as follows:

def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      @user = Factory.create(:user)
      #@user.confirm!
      sign_in @user
    end
  end

I am using Spork and Watch and my Buckets_controller_spec.rb is as simple as:

describe "User authenticated: " do

   login_user  

   @bucket = Factory(:bucket)

   it "should get index" do
     get 'index'
     response.should be_success
   end
...
end

The error is always the same:

Failures:

  1) BucketsController User authenticated: should get index
     Failure/Error: Unable to find matching line from backtrace
     ActiveRecord::RecordInvalid:
       Validation failed: Email has already been taken
     # ./lib/controller_macros.rb:12:in `block in login_user'

And it only happens when I have the Factory(:bucket). The login works fine when I don't add the Factory(:bucket).

It's always the same error. I have tried adding :email => Factory.next(:email) to the user, but no success.

Edit:

In rails c test:

ruby-1.9.2-p180 :019 > bucket = Factory(:bucket, :email => "[email protected]")
    ActiveRecord::RecordInvalid: Validation failed: Email has already been taken

    ruby-1.9.2-p180 :018 >   Bucket.create(:email => "[email protected]")
     => #<Bucket id: 2, email: "[email protected]", confirmation: nil, created_at: "2011-04-08 21:59:12", updated_at: "2011-04-08 21:59:12", user_id: nil> 

Edit 2:

I found out that the error is in the association, however, I don't know how to fix it.

  bucket.association :user
Cyndy answered 8/4, 2011 at 21:54 Comment(0)
G
6

When you define a factory with an association you need to give the factory an object to associate with whenever you use the factory.

This should work:

describe "User authenticated: " do
  login_user
  @bucket = Factory(:bucket, :user => @user)

  it "should get index" do
    get 'index'
    response.should be_success
  end
end

That way factorygirl knows to make a bucket which is associated with @user.

Grandiose answered 12/4, 2011 at 3:51 Comment(0)
P
5

Try this in your user factory:

Factory.define :user do |f|
  f.sequence(:email) { |n| "test#{n}@example.com" }
  ...
end

I think that's probably your problem. When you use f.email = "anyvalue" it's going to use that value every time. I see you were trying to create a sequence in the next block, but I'm not sure that sequence is getting used.

ALSO - be aware that if you get tests interrupted by a crash or something, sometimes bogus test data can get left in your test DB instead of being rolled back.

Very first thing I try if something worked once and then quit working is to reset the test db.

rake db:test:prepare

That will clean everything out.

If this doesn't work let me know and I'll take a second look!

Pallid answered 8/4, 2011 at 22:4 Comment(2)
thank you. I've tried all that with no success. However, I believe I found the problem but I'm not sure if this makes sense. Here it goes: When I'm creating a bucket (which is associated to a user) I'm not passing the user, so if I do Factory(:bucket, :user => User.first), it will work. Makes sense?Cyndy
Yeah, that would make sense. I have had associations like this where I must create a valid association in order for the other model to be tested.Pallid
O
0

If someone is getting this recently with your views. Try using Database Cleaner.

For more info: RailsTutorial - chapter 8.4.3 - Test database not clearing after adding user in integration test

Onetime answered 12/9, 2012 at 0:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.