使用RSpec测试控制器时模拟CanCan授权 [英] mocking CanCan authorization while testing controllers with RSpec

查看:93
本文介绍了使用RSpec测试控制器时模拟CanCan授权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我要测试的控制器:

Here is the Controller I want to test:

class UsersController < ApplicationController
  load_and_authorize_resource

  def index
    @users = User.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @users }
    end
  end

  def show
    @user = User.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @user }
    end
  end

  #other actions here

end

如您所见,我使用CanCan方法 load_and_authorize_resource ,所以我为RSpec编写了ControllerHelper:

As you can see I use CanCan method load_and_authorize_resource so I've written a ControllerHelper for RSpec:

# spec/support/controller_spec.rb
module ControllerHelper
  def should_authorize(action, subject)
    controller.should_receive(:authorize!).with(action, subject).and_return('passed!')
  end
end

然后我写了UserController Spec:

Then I've written the UserController Spec:

# spec/controllers/users_controller_spec.rb
require 'spec_helper'

describe UsersController do

  describe "GET #index" do
    before do
      @user = mock_model(User)
      should_authorize(:index, @user)
      User.stub!(:find).and_return(@user)
    end

    context "if the user passes all the authorizations" do
      it "populates an array of users" do
        User.should_receive(:find).and_return(@user)
        get :index
      end
      it "renders the :index view" do
        get :index
        response.should render_template :index
      end
    end
  end
end

但我收到此错误

Failures:

1) UsersController GET #index if the user passes all the authorizations populates an array of users
       Failure/Error: get :index
         #<UsersController:0x000000037ee750> received :authorize! with unexpected arguments
            expected: (:index, #<User:0x1bf597c @name="User_1001">)
            got: (:index, User(id: integer, email: string, encrypted_password: string, reset_password_token: string, reset_password_sent_at: datetime, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: string, last_sign_in_ip: string, created_at: datetime, updated_at: datetime, phone: string, address: string, city: string, cap: string, partitaiva: string, ragionesociale: string))
         # ./spec/controllers/users_controller_spec.rb:16:in `block (4 levels) in <top (required)>'

2) UsersController GET #index if the user passes all the authorizations renders the :index view
       Failure/Error: get :index
         #<UsersController:0x00000003802f98> received :authorize! with unexpected arguments
            expected: (:index, #<User:0x1bb0048 @name="User_1002">)
            got: (:index, User(id: integer, email: string, encrypted_password: string, reset_password_token: string, reset_password_sent_at: datetime, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: string, last_sign_in_ip: string, created_at: datetime, updated_at: datetime, phone: string, address: string, city: string, cap: string, partitaiva: string, ragionesociale: string))
         # ./spec/controllers/users_controller_spec.rb:19:in `block (4 levels) in <top (required)>'

EDIT

现在我的规格是

# spec/controllers/users_controller_spec.rb
require 'spec_helper'

describe UsersController do

  describe "GET #index" do
    before do
      @user = mock_model(User)
      should_authorize(:index, User)
      User.stub!(:all).and_return(@user)
    end

    context "if the user passes all the authorizations" do
      it "populates an array of users" do
        User.should_receive(:all).and_return(@user)
        get :index
      end
      it "renders the :index view" do
        get :index
        response.should render_template :index
      end
    end
  end
end

谢谢

enrico

推荐答案

在cancan中使用load_and_authorize_resource时,仅当操作更新,显示编辑销毁(我认为)。
当操作为 index 时,它将传递User类。

When you're using load_and_authorize_resource in cancan, it only passes an instance of user to the authorize method when the action is update, show, edit or destroy(I think). When the action is index it passes the User class instead.

这就是为什么您对 should_authorize 的期望失败的原因

That's why your expectation inside should_authorize fails

您可以在此处查看cancan的加载方式:

You can see how cancan does the loading here:

https://github.com/ryanb/cancan/blob/master/lib/cancan/controller_resource.rb#L76

这篇关于使用RSpec测试控制器时模拟CanCan授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆