在向Rails4应用程序添加授权后,RSpec控制器规范失败

在Railscast #385 & #386之后,我在Rails 4应用程序中添加了授权(rails 4.2.6,rspec-rails 3.4.2)。 添加授权后,我的所有控制器规格都会失败。

我的function规格仍然通过,因为在规范中我以admin身份登录以执行不允许访问者的操作(:edit,:update …)。 如果我允许访客进行所有操作,我的控制器规格就会通过。 但是,只有管理员才能执行的任何操作都将在控制器规范中失败。

脚手架发电机产生空的

let(:valid_session) { { } } 

它在评论中说:

#这应该返回应该在会话中的最小值集合,以便传递MyController中定义的任何filter(例如,身份validation)。

但是,我不知道如何配置:valid_session允许身份validation通过。

当我尝试在这个问题中发布的解决方案:

 def valid_session controller.stub!(:signed_in?).and_return(true) end 

我收到此错误:

 NoMethodError: undefined method `stub' for #<MyController 

因为,逻辑的所有分支路径都应该在较低级别(即控制器规范)而不是function规格上进行测试,如何让控制器规格通过?

如何配置valid_session或我可以使用哪种方法在控制器规范中传递授权?

好的,在这个博客的帮助下,我能够在向控制器添加授权后让我的控制器测试通过。

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 

然后在控制器规范, 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

你可以只为工厂用户。

 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