Ruby on rails 在运行RSpec测试时绕过CanCan::AccessDenied

Ruby on rails 在运行RSpec测试时绕过CanCan::AccessDenied,ruby-on-rails,testing,rspec,authorization,cancan,Ruby On Rails,Testing,Rspec,Authorization,Cancan,我正试图为我的餐厅模型运行一个强大的参数测试,但遇到了一个阻碍开发进程的错误。在其控制器中,我使用CanCan方法load_和\u authorize_resource,只允许管理员创建、更新和销毁这些模型实例: class RestaurantsController < ApplicationController load_and_authorize_resource param_method: :restaurant_params, find_by: :slug ... en

我正试图为我的
餐厅
模型运行一个强大的参数测试,但遇到了一个阻碍开发进程的错误。在其控制器中,我使用CanCan方法
load_和\u authorize_resource
,只允许管理员创建、更新和销毁这些模型实例:

class RestaurantsController < ApplicationController
  load_and_authorize_resource param_method:  :restaurant_params, find_by: :slug
  ...
end
有没有绕过此授权的简单方法?我看了这么多,似乎没有一个明确的答案

测试

describe RestaurantsController do
  let(:user) { FactoryGirl.create(:user, admin: true) }

  it { should permit(:name).for(:create) }
end

注意:我查看了CanCan上的over,他们说创建一个用户实例,其admin属性设置为true。即使这样,我仍然对如何在测试中插入此用户感到有点困惑。

经过一些研究,我得出结论,绕过此问题的最佳方法更多地是通过登录我的
用户
工厂,而不是处理坎坎宝石本身

根据您的设置,这可能会有所不同,但对于我的用户工厂,我将我的
admin
属性设置为
true

user.rb

FactoryGirl.define do
  factory :user do
    first_name "John"
    last_name "Doe"
    email "john@example.com"
    password "password"
    admin true
  end
end
module ControllerMacros
  def login_admin
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:admin]
      sign_in FactoryGirl.create(:user)
    end
  end
end
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'support/controller_macros'

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
    ....
    config.include Devise::TestHelpers, type: :controller

    config.extend ControllerMacros, type: :controller
end
然后,我在我的
spec
文件夹中创建了一个子目录,名为
support
,并按照提供的designe链接中的示例创建用于登录用户的适当模块方法:

spec/support/controller\u macros.rb

FactoryGirl.define do
  factory :user do
    first_name "John"
    last_name "Doe"
    email "john@example.com"
    password "password"
    admin true
  end
end
module ControllerMacros
  def login_admin
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:admin]
      sign_in FactoryGirl.create(:user)
    end
  end
end
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'support/controller_macros'

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
    ....
    config.include Devise::TestHelpers, type: :controller

    config.extend ControllerMacros, type: :controller
end
然后在我的
rails\u helper
文件中,我简单地扩展了这个模块,以便使用
login\u admin
方法。Desive示例没有提到的是,您需要
要求
此帮助程序中的
控制器\u宏
文件。有些人可能理解,但如果不小心,可能会被忽略:

spec/rails\u helper.rb

FactoryGirl.define do
  factory :user do
    first_name "John"
    last_name "Doe"
    email "john@example.com"
    password "password"
    admin true
  end
end
module ControllerMacros
  def login_admin
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:admin]
      sign_in FactoryGirl.create(:user)
    end
  end
end
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'support/controller_macros'

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
    ....
    config.include Devise::TestHelpers, type: :controller

    config.extend ControllerMacros, type: :controller
end
最后,在控制器测试中,只要在需要的地方应用
login\u admin
方法即可:

餐厅控制员测试

describe RestaurantsController do
  login_admin

  it { should permit(:name).for(:create) }
end

我绕过了cancan的
load_和\u authorize_resource
调用,因为我打算单独测试这些能力

before { allow_any_instance_of(CanCan::ControllerResource).to receive(:load_and_authorize_resource){ nil } }