Devise Test Helper-вход не работает
По какой-то причине я не могу заставить работать вспомогательный метод sign_in devise. current_user продолжает оставаться нулевым. Есть идеи, в чем может быть проблема?
Тест:
before :each do
@user = FactoryGirl.create :user
sign_in @user
end
describe "GET index" do
it "assigns all subscribers as @subscribers" do
subscriber = @user.subscribers.create! valid_attributes
get :index
assigns(:subscribers).should eq([subscriber])
end
end
Реализация:
def index
@subscribers = current_user.subscribers.all <------- ERROR
respond_to do |format|
format.html # index.html.erb
format.json { render json: @subscribers }
end
end
Error:
NoMethodError:
undefined method `subscribers' for nil:NilClass
Любая помощь ценится. Спасибо!
4 ответов:
Похоже, вы решили эту проблему, судя по вашему коду. Со мной такое случалось и раньше, и по какой-то причине каждый раз это меня достает.
Каркас rspec/rails для спецификаций контроллера не будет работать с Devise:: TestHelpers из коробки.
get :index, {}, valid_sessionВызов valid_session перезаписывает содержимое сеанса, которое устанавливает Devise. Удалите его:
get :index, {}Это должно сработать!
Если вы включаете Модуль
Confirmableв свою модельUser(или другую модель, аутентифицируемую по изобретению), то тест@user, который вы создаете, должен быть подтвержден, чтобыsign_inвступил в силу:(Я вижу, что это была не ваша проблема, но, возможно, другой читатель от этого выиграет.)before :each do @user = FactoryGirl.create :user @user.confirm! sign_in @user end
Для спецификации, убедитесь, что
include Devise::TestHelpers. Чтобы сделать это проще, в моем spec / spec_helper.rb , у меня есть:RSpec.configure do |config| config.include Devise::TestHelpers, :type => :controller endКоторый автоматически включает его для всех спецификаций контроллера.
Кроме того, вам нужно сделать это, чтобы заставить sign_in работать:
@request.env["devise.mapping"] = Devise.mappings[:user] get :newВероятно, лучше всего добавить
@request.env["devise.mapping"] = Devise.mappings[:user]к вашему before(:each). (Обратите внимание, что вы можете сделать это в своей конфигурации, если вы не хотите делать это для каждого контроллера).
Для части
current_userубедитесь, что у вас есть модельUser, где вы вызовdeviseclass User < ActiveRecord::Base # call devise to define user_signed_in? and current_user devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable # though you don't have to include all these modules endDevise использует вызов в пользовательской модели для определения
user_signed_in?иcurrent_userв контроллерах. Причина в том, что если у вас есть:class Admin < ActiveRecord::Base devise endТогда у Devise будут определены методы
admin_signed_in?иcurrent_admin.
Я столкнулся с этой проблемой при попытке проверить, что конечная точка SSO, которую я писал, создавала сеанс для пользователя. Поскольку он применялся только к одному тесту, мне просто нужно было добавить следующий блок перед моим тестом
before do @request.env["devise.mapping"] = Devise.mappings[:user] user = FactoryGirl.create(:user, :email => email, :password => "password") user.confirm! end it "should create and session for the user and redirect to home page" do
Comments