【问题标题】:How do I test the comments of the current_user in RSpec?如何在 RSpec 中测试 current_user 的评论?
【发布时间】:2015-04-30 00:43:43
【问题描述】:

所以我有一个User 那个has_many :comments

在我的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工厂:

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

想法?

【问题讨论】:

  • 您是否在测试中存根登录过程? more details here
  • 我没有。感谢您的提示。

标签: ruby-on-rails ruby-on-rails-4 rspec rspec-rails rspec3


【解决方案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

更新

除了将模块包含在 spec/rails_helper.rb 文件中的 configure 块中,您还可以在支持文件 (spec/support/devise.rb) 本身中添加 configure 块:

module SpecAuthorization
  ...
end

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

【讨论】:

  • 所以我不必在我的测试中对current_user 做任何事情,即使那是我的控制器中调用的?即current_user.comments.
  • 顺便说一句,这很有意义。我试过这样做,但我得到了这个错误:: uninitialized constant SpecAuthentication (NameError)。作为记录,我所做的是在我的spec/rails_helper.rb 中,我在我的配置块中添加了这一行:config.include SpecAuthentication。这就是我得到错误的地方。对于模块定义,我创建了一个名为spec/support/devise.rb 的文件,并在该文件中添加了该模块定义。不确定这是否会影响任何事情,但我想我会提到它。
  • 嗯,间接地你是。在我的示例中,您使用login_user 方法登录,该方法基本上是:sign_in @user。这是重要的部分。设计您的@user 工厂登录,以便@user 对象将成为当前登录的用户。 current_user 只是一个帮助方法(由 Devise 提供),供您的控制器检索该登录用户。更多信息herehere
  • 啊,对。这就说得通了。谢谢你的解释。请参阅我的其他评论:)
  • 好的,首先确保您的 rails_helper.rb 中有类似的内容:Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }let 错误告诉您在 it 块内有一个 let,而不是我在示例中显示的 describecontext 块。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多