RSpec 向 Rails4 应用程序添加授权后控制器规范失败
RSpec controller specs fail after adding authorization to Rails4 application
在 Railscast #385 & #386 之后,我已经为我的 Rails 4 应用程序添加了授权(rails 4.2.6,rspec-rails 3.4.2)。添加授权后,我所有的控制器规格都失败了。
我的功能规范仍然通过,因为在规范中我以管理员身份登录以执行不允许访问者执行的操作(:编辑,:更新...)。如果我允许访问者执行所有操作,我的控制器规格就会通过。但是,只有管理员可以执行的任何操作在控制器规范中都会失败。
脚手架生成器创建一个空的
let(:valid_session) { { } }
它在评论中说:
# This should return the minimal set of values that should be in the session
in order to pass any filters (e.g. authentication) defined in MyController.
但是,我不知道如何配置这个:valid_session以允许身份验证通过。
当我尝试此 question 中发布的解决方案时:
def valid_session
controller.stub!(:signed_in?).and_return(true)
end
我收到这个错误:
NoMethodError:
undefined method `stub' for #<MyController
既然所有的许多逻辑分支路径都应该在较低级别(即控制器规范)而不是功能规范进行测试,那么如何让控制器规范通过?
如何配置 valid_session 或者我可以使用什么其他方法来通过我的控制器规范中的授权?
你可以只工厂一个用户。
module ControllerMacros
def login_user(user = nil, options = {})
before(:each) do
@request.env["devise.mapping"] = Devise.mappings[:user]
@user = user || FactoryGirl.create(options[:user] || :user)
sign_in @user
end
end
好的,在这个 blog 的帮助下,我能够在向控制器添加授权后让我的控制器测试通过。
在spec/support/helpers/controller_macros.rb中我定义了这些方法:
module ControllerMacros
def login_admin
user = FactoryGirl.create(:admin)
allow(controller).to receive(:current_user).and_return(user)
end
def login_member
user = FactoryGirl.create(:member)
allow(controller).to receive(:current_user).and_return(user)
end
def login_visitor
allow(controller).to receive(:current_user).and_return(nil)
end
end
激活spec/support/helpers.rb中的那些方法:
RSpec.configure do |config|
config.include ControllerMacros, type: :controller
end
然后在controller spec中实现,spec/controllers/topics_controller_spec.rb:
require 'rails_helper'
RSpec.describe TopicsController, type: :controller do
let(:valid_attributes) {
{ :name => "MyTopic" }
}
let(:invalid_attributes) {
{ :name => nil }
}
before(:each) do
login_admin
end
describe "GET #index" do
it "assigns all topics as @topics" do
login_visitor
topic = Topic.create! valid_attributes
get :index, {}
expect(assigns(:topics)).to eq([topic])
end
end
describe "GET #show" do
it "assigns the requested topic as @topic" do
login_visitor
topic = Topic.create! valid_attributes
get :show, {:id => topic.to_param}
expect(assigns(:topic)).to eq(topic)
end
end
describe "GET #new" do
it "assigns a new topic as @topic" do
get :new, {}
expect(assigns(:topic)).to be_a_new(Topic)
end
end
[...]
end
这将在每次测试前以管理员身份登录。 请注意,您应该在具有权限的最低级别测试每个操作,因此 show 和 index 将作为访问者(未登录)进行测试。 如果所有操作都需要管理员权限,那么您可以使用 before do
而不是 before(:each) do
以在测试中节省一点时间。
最后,您必须从规范中删除对 valid_session
的所有提及。
在 Railscast #385 & #386 之后,我已经为我的 Rails 4 应用程序添加了授权(rails 4.2.6,rspec-rails 3.4.2)。添加授权后,我所有的控制器规格都失败了。
我的功能规范仍然通过,因为在规范中我以管理员身份登录以执行不允许访问者执行的操作(:编辑,:更新...)。如果我允许访问者执行所有操作,我的控制器规格就会通过。但是,只有管理员可以执行的任何操作在控制器规范中都会失败。
脚手架生成器创建一个空的
let(:valid_session) { { } }
它在评论中说:
# This should return the minimal set of values that should be in the session in order to pass any filters (e.g. authentication) defined in MyController.
但是,我不知道如何配置这个:valid_session以允许身份验证通过。
当我尝试此 question 中发布的解决方案时:
def valid_session
controller.stub!(:signed_in?).and_return(true)
end
我收到这个错误:
NoMethodError:
undefined method `stub' for #<MyController
既然所有的许多逻辑分支路径都应该在较低级别(即控制器规范)而不是功能规范进行测试,那么如何让控制器规范通过?
如何配置 valid_session 或者我可以使用什么其他方法来通过我的控制器规范中的授权?
你可以只工厂一个用户。
module ControllerMacros
def login_user(user = nil, options = {})
before(:each) do
@request.env["devise.mapping"] = Devise.mappings[:user]
@user = user || FactoryGirl.create(options[:user] || :user)
sign_in @user
end
end
好的,在这个 blog 的帮助下,我能够在向控制器添加授权后让我的控制器测试通过。
在spec/support/helpers/controller_macros.rb中我定义了这些方法:
module ControllerMacros
def login_admin
user = FactoryGirl.create(:admin)
allow(controller).to receive(:current_user).and_return(user)
end
def login_member
user = FactoryGirl.create(:member)
allow(controller).to receive(:current_user).and_return(user)
end
def login_visitor
allow(controller).to receive(:current_user).and_return(nil)
end
end
激活spec/support/helpers.rb中的那些方法:
RSpec.configure do |config|
config.include ControllerMacros, type: :controller
end
然后在controller spec中实现,spec/controllers/topics_controller_spec.rb:
require 'rails_helper'
RSpec.describe TopicsController, type: :controller do
let(:valid_attributes) {
{ :name => "MyTopic" }
}
let(:invalid_attributes) {
{ :name => nil }
}
before(:each) do
login_admin
end
describe "GET #index" do
it "assigns all topics as @topics" do
login_visitor
topic = Topic.create! valid_attributes
get :index, {}
expect(assigns(:topics)).to eq([topic])
end
end
describe "GET #show" do
it "assigns the requested topic as @topic" do
login_visitor
topic = Topic.create! valid_attributes
get :show, {:id => topic.to_param}
expect(assigns(:topic)).to eq(topic)
end
end
describe "GET #new" do
it "assigns a new topic as @topic" do
get :new, {}
expect(assigns(:topic)).to be_a_new(Topic)
end
end
[...]
end
这将在每次测试前以管理员身份登录。 请注意,您应该在具有权限的最低级别测试每个操作,因此 show 和 index 将作为访问者(未登录)进行测试。 如果所有操作都需要管理员权限,那么您可以使用 before do
而不是 before(:each) do
以在测试中节省一点时间。
最后,您必须从规范中删除对 valid_session
的所有提及。