8 votes

Rails 3 + Rspec 2 : Échec de la validation : L'email a déjà été pris

J'ai deux modèles, User y Bucket . User has_many Buckets et un Bucket belongs_to a User .

En factories.rb Je l'ai fait :

Factory.define :user do |user|
  user.email  "teste@test.com"
  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        "user@example.com"
  bucket.confirmation false
  bucket.association :user
end

et j'ai un module login_user comme suit :

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

J'utilise Spork and Watch et mon Buckets_controller_spec.rb est aussi simple que cela :

describe "User authenticated: " do

   login_user  

   @bucket = Factory(:bucket)

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

L'erreur est toujours la même :

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'

Et cela ne se produit que lorsque j'ai le Factory(:bucket) . La connexion fonctionne correctement lorsque je n'ajoute pas le paramètre Factory(:bucket) .

C'est toujours la même erreur. J'ai essayé d'ajouter :email => Factory.next(:email) à l'utilisateur, mais sans succès.

Editer :

En rails c test :

ruby-1.9.2-p180 :019 > bucket = Factory(:bucket, :email => "hello@hello.com")
    ActiveRecord::RecordInvalid: Validation failed: Email has already been taken

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

Editer 2 :

J'ai découvert que l'erreur se trouve dans l'association, mais je ne sais pas comment la corriger.

  bucket.association :user

6voto

David Tuite Points 5342

Lorsque vous définissez une fabrique avec une association, vous devez donner à la fabrique un objet à associer à chaque fois que vous utilisez la fabrique.

Cela devrait fonctionner :

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

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

De cette façon, factorygirl sait qu'il faut créer un seau associé à @user.

5voto

Andrew Points 14110

Essayez ceci dans votre usine d'utilisateurs :

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

Je pense que c'est probablement votre problème. Lorsque vous utilisez f.email = "anyvalue" il utilisera cette valeur à chaque fois. Je vois que vous essayez de créer une séquence dans le bloc suivant, mais je ne suis pas sûr que cette séquence soit utilisée.

De plus, sachez que si vos tests sont interrompus par un crash ou autre, des données de test erronées peuvent être laissées dans votre base de données de test au lieu d'être annulées.

La première chose que j'essaie de faire si quelque chose a fonctionné une fois puis a cessé de fonctionner, c'est de réinitialiser la base de données de test.

rake db:test:prepare

Cela permettra de tout nettoyer.

Si cela ne fonctionne pas, faites-le moi savoir et je jetterai un second coup d'œil !

0voto

LearningRoR Points 3562

Si quelqu'un a reçu ce message récemment, veuillez nous faire part de votre point de vue. Essayez d'utiliser Nettoyeur de base de données .

Pour plus d'informations : RailsTutorial - chapitre 8.4.3 - La base de données de test ne s'efface pas après l'ajout d'un utilisateur dans le test d'intégration

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X