【问题标题】:Testing Controller Concerns with Rspec on Rails 6在 Rails 6 上使用 Rspec 测试控制器问题
【发布时间】:2020-03-04 20:05:30
【问题描述】:

我无法在控制器问题上使用匿名控制器从规范访问会话或路由路径 (root_url)。

这是我的代码

module SecuredConcern
  extend ActiveSupport::Concern

  def logged_in?
    session[:user_info].present?
  end

  def redirect_to_login
    redirect_to login_path unless logged_in?
  end

  def redirect_to_home
    redirect_to root_path if logged_in?
  end
end

和规格

require 'rails_helper'

describe SecuredConcern, type: :controller do
  before do
    class FakesController < ApplicationController
      include SecuredConcern
    end
  end

  after { Object.send :remove_const, :FakesController }
  let(:object) { FakesController.new }
  # let(:session) {create(:session, user_info: '')}

  describe 'logged_in' do
    it "should return false if user is not logged in" do
      expect(object.logged_in?).to eq(false)
    end
  end
end

这是踪迹:

Module::DelegationError:
       ActionController::Metal#session delegated to @_request.session, but @_request is nil: #<FakesController:0x00007f9856c04c20 @_action_has_layout=true, @rendered_format=nil, @_routes=nil, @_request=nil, @_response=nil>
     # ./app/controllers/concerns/secured_concern.rb:9:in `logged_in?'
     # ./spec/controllers/concerns/secured_concern_spec.rb:21:in `block (3 levels) in <main>'
     # ------------------
     # --- Caused by: ---
     # NoMethodError:
     #   undefined method `session' for nil:NilClass
     #   ./app/controllers/concerns/secured_concern.rb:9:in `logged_in?'

配置更新为config.infer_base_class_for_anonymous_controllers = true

关于我在这里做错了什么的任何指示?

【问题讨论】:

  • 控制台日志说会话委托给@_request.session,但@_request 为零。我的解决方案是为 FakeController 创建一个假方法,以及该假方法的路由。然后在请求规范中测试logged_in?

标签: ruby-on-rails ruby rspec-rails ruby-on-rails-6 activesupport-concern


【解决方案1】:

这是我使用RSpec.shared_examples解决它的方法

在我的控制器规范中,我包含了这个问题:

# spec/controllers/home_controller_spec.rb
RSpec.describe HomeController, type: :controller do
  it_behaves_like 'SecuredConcern', HomeController
end

在我的关注规范中:

# spec/shared/secured_concern_spec.rb
require 'rails_helper'

RSpec.shared_examples 'SecuredConcern' do |klass|
  describe '#logged_in?' do
    it "should return true if user is logged in" do
      session[:user_info] = {uid: 1}
      expect(subject.logged_in?).to eq(true)
    end

    it "should return false if user is not logged in" do
      expect(subject.logged_in?).to eq(false)
    end
  end
end

希望对遇到类似问题的人有所帮助。

【讨论】:

  • 谢谢。 subject 哪里来的?
  • @RicardoGreen subject 是所描述的类的一个实例,由 Rspec 自己提供,要么是 implicitly(传递给 describe 方法的第一个参数),要么是 explicitly 内的 @987654329 @ 堵塞。要访问类本身,您可以使用described_class
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多