Работая с RSpec & Capybara, я получаю интересный режим сбоя теста, который исчезает с несколькими тонкими перестановками строк в тестовом примере ... вещи, которые не должны иметь значения.
Я разрабатываю собственную систему аутентификации. В настоящее время он работает, и я могу войти / выйти из браузера, сеанс работает и т. Д. И т. Д. Однако попытка проверить это не удалась. Что-то происходит, что я не совсем понимаю, что, кажется, зависит от порядка (казалось бы) несвязанных вызовов.
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
Так как этот тест не пройден ... вход не выполнен. После вставки вызовов «отладчика» в спецификацию и контроллер я могу понять, почему: пользователь не вставляется в базу данных в отношении контроллера:
Редактировать добавление в 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
в консоли, в вышеуказанной точке останова:
1.9.2 vox@Alpha:~/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 >
Однако, если я переставлю несколько строк в своем тесте, поместив строку «два» над строкой «один»:
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
Я получаю это в консоли (та же точка останова, что и выше):
1.9.2 vox@Alpha:~/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
Для краткости я опустил полный дамп содержимого пользовательского объекта, но могу вас заверить, что тест завершается, как и ожидалось.
Такое поведение перестановки строк для прохождения теста не очень хорошо согласуется с моим представлением о том, что должно происходить с этими командами, и оказалось весьма полезным для моего тестирования в других областях.
Есть какие-нибудь намеки на то, что здесь происходит?
Я искал в Google и SO идеи, которые представляют эту проблему, и нет недостатка в SO вопросах о RSpec / Capybara и Sessions. Хотя, похоже, ничего не подходит.
Спасибо за внимание.
Обновление
Я добавил точку останова (непосредственно перед вызовом посещения) и некоторую отладку в тесте и вернулся с этим:
(rdb:1) user
#<User id: 1, login_count: 1, email: "testuser1@website.com", encrypted_password: "11f40764d011926eccd5a102c532a2b469d8e71249f3c6e2f8b...", salt: "1313613794">
(rdb:1) User.all
[#<User id: 1, login_count: 1, email: "testuser1@website.com", 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
[]
Так ясно, что что-то в пути, которое посещает, говорит Factory Girl, что оно сделано с объектом пользователя, и поэтому она удаляет его?
Редактировать После тщательной проверки test.log, ничего не выдает никакого удаления. Так что я более или менее вернулся на круги своя.