使用RSpec测试控制器时模拟CanCan授权 [英] mocking CanCan authorization while testing controllers with RSpec
问题描述
这是我要测试的控制器:
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屋!