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


Любая помощь ценится. Спасибо!

577   4  

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, где вы вызов devise

class 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
end

Devise использует вызов в пользовательской модели для определения 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

    Ничего не найдено.