2015-04-30 1 views
0

Итак, у меня есть User, что has_many :comments.Как проверить комментарии current_user в RSpec?

В моей Comments#Index, у меня есть это:

def index 
    @comments = current_user.comments 
    end 

Внутри моего Rspec.config... блока в rails_helper.rb у меня есть это:

# Add Config info for Devise 
    config.include Devise::TestHelpers, type: :controller 

Мои comments_controller_spec.rb выглядит следующим образом:

describe 'GET #index' do 
    it "populates an array of comments that belong to a user" do 
     user = create(:user) 
     node = create(:node) 
     comment1 = create(:comment, node: node, user: user) 
     comment2 = create(:comment, node: node, user: user) 
     get :index, { node_id: node } 
     expect(assigns(:comments)).to match_array([comment1, comment2]) 
    end 
    it "renders the :index template" 
    end 

Этот это мой Users.rb f actory:

FactoryGirl.define do 
    factory :user do 
    association :family_tree 
    first_name { Faker::Name.first_name } 
    last_name { Faker::Name.last_name } 
    email { Faker::Internet.email } 
    password "password123" 
    password_confirmation "password123" 
    bio { Faker::Lorem.paragraph } 
    invitation_relation { Faker::Lorem.word } 
    # required if the Devise Confirmable module is used 
    confirmed_at Time.now 
    gender 1 
    end 
end 

Это мой Comments завод:

FactoryGirl.define do 
    factory :comment do 
    association :node 
    message { Faker::Lorem.sentence } 

    factory :invalid_comment do 
     message nil 
    end 
    end 
end 

Это ошибка я получаю в настоящее время:

Failure/Error: get :index, { node_id: node } 
NoMethodError: 
    undefined method `comments' for nil:NilClass 

Мысли?

+2

Вы заглушили входной сигнал в вашем тесте? [подробнее] [https://github.com/plataformatec/devise/wiki/How-To:-Stub-authentication-in-controller-specs) – AbM

+0

Я этого не делал. Спасибо за совет. – marcamillion

ответ

1

Вы должны войти в первую:

describe 'GET #index' do 
    let(:user) { create(:user) } 
    let(:node) { create(:node) } 
    let(:comment1) { create(:comment, node: node, user: user) } 
    let(:comment2) { create(:comment, node: node, user: user) } 

    before do 
    @request.env["devise.mapping"] = Devise.mappings[:user] 
    sign_in user 
    end 

    it "populates an array of comments that belong to a user" do 
    get :index, { node_id: node } 
    expect(assigns(:comments)).to match_array [comment1, comment2] 
    end 
end 

Вы также можете создать модуль в вашем spec/support директории со следующим кодом:

module SpecAuthentication 
    def login_user 
    @request.env["devise.mapping"] = Devise.mappings[:user] 
    @user = FactoryGirl.create :user 
    sign_in @user 
    end 
end 

и включить его в свой RSpec.configure блок:

config.include SpecAuthentication 

Теперь вы можете позвонить в login_user методом в лету Ур спецификации:

describe 'GET #index' do 
    let(:node) { create(:node) } 
    let(:comment1) { create(:comment, node: node, user: @user) } 
    let(:comment2) { create(:comment, node: node, user: @user) } 

    before { login_user } 

    it "populates an array of comments that belong to a user" do 
    get :index, { node_id: node } 
    expect(assigns(:comments)).to match_array [comment1, comment2] 
    end 
end 

Update

Вместо включения модуля в configure блока в файле spec/rails_helper.rb, вы можете также добавить configure блок в файле поддержки (spec/support/devise.rb) сам по себе:

module SpecAuthorization 
    ... 
end 

RSpec.configure do |config| 
    config.include SpecAuthorization 
end 
+0

Так что мне не нужно ничего делать с 'current_user' в моих тестах, даже если это то, что вызывается в моем контроллере? то есть 'current_user.comments'. – marcamillion

+0

Кстати, это имеет смысл. Я попытался сделать это, но я получил эту ошибку: ': uninitialized constant SpecAuthentication (NameError)'. Для записи то, что я сделал, было внутри моего spec/rails_helper.rb. Я добавил эту строку внутри моего конфигурационного блока: 'config.include SpecAuthentication'. Вот где я получаю ошибку. Для определения модуля я создал файл под названием 'spec/support/devise.rb', и внутри этого файла я добавил это определение модуля. Не уверен, что это повлияло на что-либо, но подумал, что я бы сказал об этом. – marcamillion

+1

Ну, косвенно вы. В моем примере вы входите в систему с помощью метода 'login_user', который в основном выполняет:' sign_in @ user'. Это важная часть.Devise подписывает вашу фабрику '@ user', так что объект' @ user' будет в данный момент подписанным пользователем. 'current_user' - это просто вспомогательный метод (предоставляемый Devise) для ваших контроллеров для получения этого подписанного пользователя. Подробнее [здесь] (https://github.com/plataformatec/devise#controller-filters-and-helpers) и [здесь] (https://github.com/plataformatec/devise#test-helpers). – newmediafreak