如何测试 RSpec 中 current_user 的评论?
How do I test the comments of the current_user in RSpec?
所以我有一个 User
has_many :comments
。
在我的 Comments#Index
中,我有这个:
def index
@comments = current_user.comments
end
在 rails_helper.rb
的 Rspec.config...
块中,我有这个:
# 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
工厂:
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
想法?
您需要先登录:
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
更新
除了在 spec/rails_helper.rb
文件的 configure
块中包含模块,您还可以在支持文件 (spec/support/devise.rb
) 本身中添加一个 configure
块:
module SpecAuthorization
...
end
RSpec.configure do |config|
config.include SpecAuthorization
end
所以我有一个 User
has_many :comments
。
在我的 Comments#Index
中,我有这个:
def index
@comments = current_user.comments
end
在 rails_helper.rb
的 Rspec.config...
块中,我有这个:
# 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
工厂:
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
想法?
您需要先登录:
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
更新
除了在 spec/rails_helper.rb
文件的 configure
块中包含模块,您还可以在支持文件 (spec/support/devise.rb
) 本身中添加一个 configure
块:
module SpecAuthorization
...
end
RSpec.configure do |config|
config.include SpecAuthorization
end