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

问题描述 投票:1回答:2

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

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

脚手架生成器创建一个空的

  let(:valid_session) { { } }

它在评论中说:

#这应该返回会话中应包含的最小值集,以通过MyController中定义的任何过滤器(例如,身份验证)。

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

当我尝试此问题中发布的解决方案时:

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

我收到此错误:

NoMethodError:
        undefined method `stub' for #<MyController

由于逻辑的所有许多分支路径都应在较低的级别(即控制器规格)而不是功能规格上进行测试,我如何使控制器规格通过?

如何配置valid_session或我可以使用什么其他方法通过控制器规格中的授权?

ruby-on-rails ruby-on-rails-4 rspec rspec-rails
2个回答
2
投票

好的,在此博客的帮助下,我向控制器添加了授权后就能通过控制器测试。

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提及。


0
投票

您可以将一个用户工厂化。

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
© www.soinside.com 2019 - 2024. All rights reserved.