Rails:如何编写匿名规范控制器来测试授权

时间:2014-11-26 16:18:20

标签: ruby-on-rails ruby model-view-controller rspec

我有一个控制器AdminController,它为CMS的其余部分设置各种授权级别。因为没有控制器动作,只有方法,我开始研究如何针对控制器测试这些。

我得出的结论是,他们需要独立于他们使用的控制器进行测试(如果可能的话,我想避免集成测试,如水豚等)。

我发现了一些像one这样的文章来帮助我。

到目前为止,我已经编写了此规范,但未能解决以下错误。我不确定它是否诚实,并希望在这里SO社区对我想要达到的目标所说的话。

describe AdminController do

    controller do
      before_filter :authorize_fixture_uploader!

      def index 
        render text: 'Hello World'
      end 
    end

    let(:admin){FactoryGirl.create(:admin)}

    describe "authentication" do 
      before do
        sign_in admin
        allow(controller).to receive(:current_admin).and_return(admin)
      end

      describe "authorize_fixture_uploader! helper" do 

        context "signed in" do 
          before do 
            allow(:admin).to receive(:authorize_fixture_uploader!).and_return(false)
            get :index 
          end

          it "redirects do admin_home_path" do 
            expect(response).to redirect_to admin_home_path
          end
        end
      end
    end
   end

这是控制器

class AdminController < ApplicationController

  before_filter :authenticate_admin!


  def authorize_fixture_uploader!
    unless current_admin.fixture_uploader?
      return redirect_to(admin_home_path)
    end
  end
end

此测试给出了错误

  1) AdminController authentication authorize_fixture_uploader! helper signed in redirects do admin_home_path
     Failure/Error: allow(:admin).to receive(:authorize_fixture_uploader?).and_return(false)
     TypeError:
       can't define singleton

我很担心,因为我对此的整体态度是错误的。肯定会得到帮助。

感谢@ blelump的回答。

我有一种导致第一个问题的类型。但现在我收到了错误

   undefined method `authorize_fixture_uploader?' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_1::Nested_1::Nested_1:0x007f9357857108>

这背后的逻辑我扔了一点。我如何独立于它们使用的控制器来测试这些方法?

2 个答案:

答案 0 :(得分:1)

你有一个错字:

allow(:admin).to receive(:authorize_fixture_uploader!).and_return(false)

现在,您正尝试将authorize_fixture_uploader!添加到Symbol。只需从controller变量:

开始
allow(controller).to receive(:authorize_fixture_uploader!).and_return(false)

答案 1 :(得分:0)

除了上面的blelump注意力不集中,我的方法中的真正缺陷是缺乏路线。我从关键实验室http://pivotallabs.com/adding-routes-for-tests-specs-with-rails-3/找到了一篇非常有用的文章,它挽救了这一天。

阅读文章,但它基本归结为此。

require 'spec_helper'

class InheritsFromAdminController < AdminController
  def show
    render :text => "foo"
  end
end

describe InheritsFromAdminController do

  before do
    Rails.application.routes.draw do

      # add the route that you need in order to test
      match '/foo' => "inherits_from_admin#show"

      # re-drawing routes means that you lose any routes you defined in routes.rb
      # so you have to add those back here if your controller references them
      match '/login' => "sessions/new", :as => login

    end
  end

  after do

    # be sure to reload routes after the tests run, otherwise all your 
    # other controller specs will fail
    Rails.application.reload_routes!

  end

  it "requires logged-in users" do
    get :show
    response.should redirect_to("/login")
  end
end