RSpec测试中sign_in方法未定义问题排查求助
解决RSpec请求测试中Devise
sign_in方法未定义的问题 问题场景
编写请求类型的控制器测试,验证GET请求返回200状态码,但按网上方案在spec_helper.rb引入Devise助手后,仍然报错:
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
问题原因
你的测试类型是type: :request,但当前spec_helper.rb里只给controller、view、routing类型的测试引入了Devise控制器助手,请求测试需要使用Devise集成测试助手才能获得sign_in方法。
解决方案
修改spec_helper.rb中的RSpec配置块,添加针对request类型的Devise助手引入:
- 对于Devise 4.1及以上版本,使用
Devise::Test::IntegrationHelpers(推荐):
RSpec.configure do |config| # 给控制器、视图、路由测试保留原有助手 config.include Devise::Test::ControllerHelpers, type: [:controller, :view, :routing] # 给请求测试添加集成助手 config.include Devise::Test::IntegrationHelpers, type: :request # 其他原有配置保持不变 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
- 如果是Devise旧版本(低于4.1),可替换为
Devise::TestHelpers,但优先建议升级Devise并使用集成助手。
修改后重新运行测试,sign_in方法即可正常调用,测试能顺利验证请求状态码。
内容的提问来源于stack exchange,提问作者Misha Krul
相关产品推荐
相关产品推荐

