3 votes

échec du test rspec lors du passage de l'initialisation des attributs à Factory

Cela n'a aucun sens pour moi, j'espère que quelqu'un pourra m'aider. J'obtiens l'échec d'un seul test lors de la création d'un utilisateur à l'aide d'une usine (d'autres tests similaires réussissent).

Dans mon fichier de test user_spec.rb, l'utilisateur a été créé à l'origine comme ceci. En utilisant cette approche d'initialisation, tous les tests passent.


CRÉATION DE L'UTILISATEUR

user_spec.rb (sans usine)

describe User do

  before do
  @user = User.new(name: "Example User", email: "user@example.com", 
                   password: "foobar", password_confirmation: "foobar", 
                   username: "username")
  end

La plupart des autres tests de l'application utilisent des usines. J'ai donc décidé de remplacer ce qui précède par un appel à la fabrique.

user_spec.rb (avec usine)

describe User do

  before do
  @user = FactoryGirl.create(:user)
  end

FACTORY

L'usine ressemble à ça.

usines.rb

FactoryGirl.define do
      factory :user do
        sequence(:name)  { |n| "Person #{n}" }
        sequence(:email) { |n| "person_#{n}@example.com" }
        password              "foobar"
        password_confirmation "foobar"
        sequence(:username) { |n| "username_#{n}" }

ÉCHEC DU TEST

Voici l'échec du test lors de l'utilisation de la fabrique pour créer l'utilisateur.

user_spec.rb

Failures:

  1) User when email address is already taken 
     Failure/Error: it { should_not be_valid }
       expected valid? to return false, got true
     # ./spec/models/user_spec.rb:101:in `block (3 levels) in <top (required)>'

Finished in 12.61 seconds
178 examples, 1 failure, 2 pending

TEST

Voici la partie du test qui échoue lors du passage à l'usine.

describe "when email address is already taken" do
    before do
      user_with_same_email = @user.dup
        user_with_same_email.email = @user.email.upcase
        user_with_same_email.save
    end

    it { should_not be_valid }
  end

INSPECTION DE L'UTILISATEUR ET DE L'UTILISATEUR.DUP

Ma première idée était que l'utilisation du .dup sur l'utilisateur créé en usine causait peut-être des problèmes. Voici l'@user et l'@user.dup en sortie de leur utilisation dans le test ci-dessus (en ajoutant les lignes puts @user.inspect y puts user_with_same_email.inspect dans le bloc de description. Ces deux puts sont après le user_with_same_email.save ).

SANS USINE (Test réussi)

@user

#<User id: nil, name: "Example User", email: "user@example.com", 
created_at: nil, updated_at: nil, 
password_digest: "$2a$04$I/71i.fpTwfp4PqRwAvU4eUEjEkW/wubx6uVBqfNBShq...", 
remember_token: nil, admin: false, username: "username">

utilisateur_avec_same_email

#<User id: 1178, name: "Example User", email: "USER@EXAMPLE.COM", 
created_at: "2012-04-24 06:01:07", updated_at: "2012-04-24 06:01:07", 
password_digest: "$2a$04$I/71i.fpTwfp4PqRwAvU4eUEjEkW/wubx6uVBqfNBShq...", 
remember_token: "rMS9jM0d4lobLc-A-pTTqA", admin: false, username: "username">

AVEC FACTORY (échec du test)

@user

#<User id: 739, name: "Person 67", email: "person_67@example.com", 
created_at: "2012-04-24 05:54:28", updated_at: "2012-04-24 05:54:28", 
password_digest: "$2a$04$n4tToBVM2elz92cfHPKvte6dfHSBj4jDxG.w6DyKtGUR...", 
remember_token: "fy2iifmhXVTFa1__d1dBJg", admin: false, username: "username_67">

utilisateur_avec_same_email

#<User name: "Person 67", email: "PERSON_67@EXAMPLE.COM", 
created_at: nil, updated_at: nil, 
password_digest: "$2a$04$n4tToBVM2elz92cfHPKvte6dfHSBj4jDxG.w6DyKtGUR...", 
remember_token: "fy2iifmhXVTFa1__d1dBJg", admin: false, username: "username_67">

Ce qui ressort de ce qui précède est que @user n'est pas déjà sauvegardé sans utiliser la fabrique, alors qu'en utilisant la fabrique @user est sauvegardé. Je ne vois pas comment cela affecte le test dans ce cas.

Toute aide serait appréciée. Merci !

(Le code ci-dessus provient du Rails Tutorial de Michael Hartl, je travaille sur certains des éléments suivants extensions des fonctionnalités des applications qu'il mentionne à la fin du tutoriel).

4voto

EricM Points 744

L'usine met l'enregistrement dans la BD. User.new ne le fait pas tant qu'il n'est pas enregistré. Le test original ne vérifie pas si user_with_same_email est créé, mais plutôt qu''il' (subject { @user }) ne peut pas être créé parce que l'email existe. Après avoir apporté votre modification à l'@user, j'ai dû réécrire le test :

describe "when email address is already taken" do
  let (:user_with_same_email)  { @user.dup }

  specify { user_with_same_email.should_not be_valid }
end

1voto

Brett Sanders Points 557

Merci Eric. Je m'appuie sur votre test ....

Le test original vérifiait également la sensibilité à la casse ainsi que l'unicité. Ce test passe et semble faire l'affaire. Des idées ?

describe "when email address is already taken" do
  let(:user_with_same_email) { @user.dup }
  before do 
    user_with_same_email.email = @user.email.upcase 
    user_with_same_email.save
  end
  specify { user_with_same_email.should_not be_valid }
end

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