ruby on rails 3 - Falla en la prueba rspec al cambiar de los atributos de inicialización a fábrica
ruby-on-rails-3 testing (2)
Esto no tiene sentido para mí, espero que alguien pueda ayudar. Recibo una falla de prueba única al crear un usuario que usa una fábrica (pase de pruebas aparentemente similar).
En mi archivo de prueba user_spec.rb, el usuario fue creado originalmente así. Usando este enfoque de inicialización, todas las pruebas pasan.
CREACIÓN DE USUARIO
user_spec.rb (sin fábrica)
describe User do
before do
@user = User.new(name: "Example User", email: "[email protected]",
password: "foobar", password_confirmation: "foobar",
username: "username")
end
La mayoría de las otras pruebas para la aplicación usan fábricas. Por lo tanto, decidió reemplazar lo anterior con una llamada a fábrica.
user_spec.rb (con fábrica)
describe User do
before do
@user = FactoryGirl.create(:user)
end
FÁBRICA
La fábrica se ve así.
factories.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}" }
FALLO DE PRUEBA
Aquí está la falla de prueba cuando se usa la fábrica para crear el usuario.
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
PRUEBA
Aquí está la parte de la prueba que falla al cambiar a la fábrica.
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
INSPECCIÓN DE USUARIO Y USUARIO
Mi primer pensamiento fue tal vez usar el .dup en el usuario creado de fábrica que causaba problemas. Aquí está el @user y el @ user.dup cuando salen de su uso en la prueba anterior (al agregar las líneas puts @user.inspect
y puts user_with_same_email.inspect
en el bloque de descripción. Ambas puts
encuentran después del user_with_same_email.save
)
SIN FÁBRICA (Pases de prueba)
@usuario
#<User id: nil, name: "Example User", email: "[email protected]",
created_at: nil, updated_at: nil,
password_digest: "$2a$04$I/71i.fpTwfp4PqRwAvU4eUEjEkW/wubx6uVBqfNBShq...",
remember_token: nil, admin: false, username: "username">
user_with_same_email
#<User id: 1178, name: "Example User", email: "[email protected]",
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">
CON FÁBRICA (Prueba falla)
@usuario
#<User id: 739, name: "Person 67", email: "[email protected]",
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">
user_with_same_email
#<User name: "Person 67", email: "[email protected]",
created_at: nil, updated_at: nil,
password_digest: "$2a$04$n4tToBVM2elz92cfHPKvte6dfHSBj4jDxG.w6DyKtGUR...",
remember_token: "fy2iifmhXVTFa1__d1dBJg", admin: false, username: "username_67">
Lo que se destaca más arriba es que @user aún no está guardado sin usar la fábrica, mientras que cuando se usa el @user de fábrica se guarda. Simplemente no veo cómo esto afecta la prueba en este caso.
Cualquier ayuda sería apreciada. ¡Gracias!
(El código anterior proviene del Tutorial Rails de Michael Hartl, estoy trabajando en algunas de las extensiones de funciones de la aplicación que menciona al final del tutorial).
Gracias Eric. Sobre la base de su prueba ...
La prueba original también estaba probando la sensibilidad de mayúsculas y minúsculas así como la singularidad. Esta prueba pasa y parece hacer el truco. ¿Alguna idea?
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
La fábrica pone el registro en el DB. User.new no funciona hasta que se guarda. La prueba original no verifica si se crea user_with_same_email, sino que ''it'' (subject {@user}) no se puede crear porque el correo electrónico existe. Después de hacer su cambio al @ usuario, tuve que volver a escribir la prueba:
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