Trabajando con RSpec & Capybara, estoy obteniendo un modo de falla de prueba interesante que se va con algunos arreglos sutiles de líneas en el caso de prueba ... cosas que no deberían importar.Factory Girl/Capybara borrando registros de la base de datos mid-test?
Estoy desarrollando mi propio sistema de autenticación. Actualmente está funcionando y puedo iniciar sesión/salir con el navegador y la sesión funciona, etc. etc. Sin embargo, tratar de probar esto está fallando. Está sucediendo algo que no entiendo del todo, que parece depender del orden de las llamadas (aparentemente) no relacionadas.
require 'spec_helper'
describe "Sessions" do
it 'allows user to login' do
#line one
user = Factory(:user)
#For SO, this method hashes the input password and saves the record
user.password! '2468'
#line two
visit '/sessions/index'
fill_in 'Email', :with => user.email
fill_in 'Password', :with => '2468'
click_button 'Sign in'
page.should have_content('Logged in')
end
end
Como es, esa prueba falla ... el inicio de sesión falla. Después de insertar 'depurador' pone en tanto la especificación y el controlador Puedo ver por qué: el usuario no está siendo insertado en la base de datos por lo que el controlador está preocupado:
Editar añadiendo en ApplicationController
class ApplicationController < ActionController::Base
helper :all
protect_from_forgery
helper_method :user_signed_in?, :guest_user?, :current_user
def user_signed_in?
!(session[:user_id].nil? || current_user.new_record?)
end
def guest_user?
current_user.new_record?
end
def current_user
@current_user ||= session[:user_id].nil? ? User.new : User.find(session[:user_id])
rescue ActiveRecord::RecordNotFound
@current_user = User.new
flash[:notice] = 'You\'ve been logged out.'
end
end
class SessionsController < ApplicationController
def login
user = User.where(:email=>params[:user][:email]).first
debugger ###
if !user.nil? && user.valid_password?(params[:user][:password])
#engage session
else
#run away
end
end
def logout
reset_session
redirect_to root_path, :notice => 'Logget Out.'
end
end
en la consola, en el punto de ruptura por encima de:
1.9.2 [email protected]:~/Sites/website$ rspec spec/controllers/sessions_controller_spec.rb
/Users/vox/Sites/website/app/controllers/sessions_controller.rb:7
if !user.nil? && user.valid_password?(params[:user][:password])
(rdb:1) irb
ruby-1.9.2-p180 :001 > User.all.count
=> 0
ruby-1.9.2-p180 :002 >
Sin embargo, si yo reordenar unas pocas líneas en mi prueba, poniendo la línea 'dos' por encima de la línea 'uno':
describe "Sessions" do
it 'allows user to login' do
#line two
visit '/sessions/index'
#line one
user = Factory(:user)
#For SO, this method hashes the input password and saves the record
user.password! '2468'
fill_in 'Email', :with => user.email
fill_in 'Password', :with => '2468'
click_button 'Sign in'
page.should have_content('Logged in')
end
end
me sale esto en la consola (el mismo que el anterior punto de ruptura):
1.9.2 [email protected]:~/Sites/website$ rspec spec/controllers/sessions_controller_spec.rb
/Users/vox/Sites/website/app/controllers/sessions_controller.rb:7
if !user.nil? && user.valid_password?(params[:user][:password])
(rdb:1) irb
ruby-1.9.2-p180 :001 > User.all.count
=> 1
En aras de la brevedad he omitido el volcado completo de los contenidos del objeto de usuario, pero puedo asegurarles que la prueba se completa como se esperaba
Este comportamiento de líneas de intercambio para pasar la prueba realmente no encaja bien con mi idea de lo que debería estar pasando con estos comandos y ha demostrado ser bastante compatible con mis pruebas en otras áreas.
¿Alguna pista sobre lo que está pasando aquí?
He recorrido google y SO para obtener ideas que presentan este problema, y no hay escasez de preguntas sobre RSpec/Capybara y Sessions. Sin embargo, nada parecía encajar del todo bien.
Gracias por mirar.
actualización
He añadido un punto de interrupción (justo antes de una llamada visita) y algunos de depuración para la prueba y volver con esto:
(rdb:1) user
#<User id: 1, login_count: 1, email: "[email protected]", encrypted_password: "11f40764d011926eccd5a102c532a2b469d8e71249f3c6e2f8b...", salt: "1313613794">
(rdb:1) User.all
[#<User id: 1, login_count: 1, email: "[email protected]", encrypted_password: "11f40764d011926eccd5a102c532a2b469d8e71249f3c6e2f8b...", salt: "1313613794">]
(rdb:1) next
/Users/vox/Sites/website/spec/controllers/sessions_controller_spec.rb:19
fill_in 'Email', :with => user.email
(rdb:1) User.all
[]
algo tan claramente a lo largo de la manera en que ¿Hacer visitas le dice a Factory Girl que está hecho con el objeto de usuario y lo elimina?
Editar Después de inspeccionar test.log con cuidado, no se emite ninguna eliminación. Así que estoy más o menos de vuelta al punto de partida.
Lo mejor es configurarlo en el spec_helper.rb. – iltempo
Esto me dejó perplejo todo el día ya que tenía muchas distracciones que me llevaron por el camino equivocado. ¡Gracias! – Rimian