RSpec controller specs fail after adding authorization to Rails4 application

余生颓废 提交于 2019-12-01 12:39:46

Ok, with the help of this blog I was able to get my controller tests to pass after adding authorization to the controllers.

In spec/support/helpers/controller_macros.rb I defined these methods:

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

To activate those methods in spec/support/helpers.rb:

RSpec.configure do |config|
  config.include ControllerMacros, type: :controller
end

And then implement it in the 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

This will login as admin before each test. Note that you should test each action at the lowest level that has permission, so show and index are tested as a visitor (not-logged in). If all actions need admin permission then you can use before do instead of before(:each) do to save a little time in the tests.

Finally you must remove all mention of valid_session from the spec.

You could just factory a user.

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!