rspec 的未定义方法sign_in

问题描述 投票:0回答:1

我正在编写一个简单的控制器测试,以确保我们在 GET 请求时获得 200 状态。我在网上遇到的每个答案都说要确保我们在

Devise
中包含正确的
spec_helper.rb
助手,但我尝试过的似乎都没有帮助。

错误:

NoMethodError:
       undefined method `sign_in' for #<RSpec::ExampleGroups::ApplicationFunnelController::Index::WhenAccessed "returns 200" (./spec/requests/application_funnel_controller_spec.rb:7)>

控制器测试:

require 'spec_helper'

RSpec.describe ApplicationFunnelController, type: :request do
  describe "index" do
    context "when accessed" do
      it "returns 200" do
        user = FactoryBot.create(:user)
        group = FactoryBot.create(:group, name: 'Testers')
        user.groups << group
        sign_in user

        get become_a_member_path

        expect(response.status).to eq 200
      end
    end
  end
end

spec_helper.rb:

ENV["RAILS_ENV"] ||= "test"
require_relative "../config/environment"
require "rails/test_help"
require "database_cleaner"
require "rspec/rails"
require "capybara/rspec"
require "capybara/rails"
require "devise"

class ActiveSupport::TestCase
  # Run tests in parallel with specified workers
  parallelize(workers: :number_of_processors)

  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all

  # Add more helper methods to be used by all tests here...
end

RSpec.configure do |config|
  config.include Devise::Test::ControllerHelpers, type: :controller
  config.include Devise::Test::ControllerHelpers, type: :view
  config.include Devise::TestHelpers, type: :controller
  config.include Devise::Test::ControllerHelpers, type: :routing
  config.include Devise::TestHelpers, type: :routing
  config.infer_spec_type_from_file_location!

  DEFAULT_CLEANER_STRATEGY = :transaction

  def with_truncation
    DatabaseCleaner.strategy = :truncation
    yield
  ensure
    DatabaseCleaner.strategy = DEFAULT_CLEANER_STRATEGY
  end

  config.include ActiveSupport::Testing::TimeHelpers

  config.before :suite do
    ActiveJob::Base.queue_adapter = :test
    DatabaseCleaner.strategy = DEFAULT_CLEANER_STRATEGY
    unless ENV["SEED"] == "false"
      DatabaseCleaner.clean_with(:truncation, except: %w(ar_internal_metadata schema_migrations))
    end
    Rails.application.load_tasks
  end

  config.before { ActionMailer::Base.deliveries.clear }
end
testing rspec request capybara specifications
1个回答
0
投票

经过几次搜索并阅读文档后,我认为找到了答案。

首先,据我所知,控制器规范中的

type: :request
不起作用。 控制器规格请求规格之间存在差异。我建议您阅读提供的链接,以便您可以考虑要在代码库中包含哪种类型的测试。

现在,假设您想在控制器规范中登录用户工厂,您可以做的是创建一个

ControllerMacros
模块,并将其放入
spec/support
:

# =================================
# spec/support/controller_macros.rb

module ControllerMacros
  def login_user(user)
    @request.env["devise.mapping"] = Devise.mappings[:user]
    sign_in user
  end
end

# ====================
# spec/rails_helper.rb

require_relative 'support/controller_macros'

RSpec.configure do |config|
  # For Devise > 4.1.1
  config.include Devise::Test::ControllerHelpers, :type => :controller
  # Use the following instead if you are on Devise <= 4.1.1
  # config.include Devise::TestHelpers, :type => :controller
  config.extend ControllerMacros, :type => :controller
end

# ======================================================
# spec/controllers/application_funnel_controller_spec.rb

RSpec.describe ApplicationFunnelController do
  describe "index" do
    context "when accessed" do
      # You can optionally add this in you example.
      before do
        FactoryBot.create(:user).tap do |user|
          group = FactoryBot.create(:group, name: 'Testers')
          user.groups << group
          login_user user
        end
      end

      it "returns 200" do
        get become_a_member_path

        expect(response.status).to eq 200
      end
    end
  end
end

以这种方式加载模块:

config.extend ControllerMacros, :type => :controller

应该允许您在控制器规格中使用

login_user
方法。

如果重复起来很烦人,您可以选择这样做:

module ControllerMacros
  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      user = FactoryBot.create(:user)
      sign_in user
    end
  end
end

只需调用控制器规范中的方法即可:

RSpec.describe ApplicationFunnelController do
  login_user

  # Tests here...
end

您可以在其存储库 wiki 中找到有关使用 Rspec 测试 Devise 的更多信息:

© www.soinside.com 2019 - 2024. All rights reserved.