Using an anonymous controller
controller メソッドを使用して、記述されたクラスから継承する匿名コントローラーを定義します。これは、グローバルエラーハンドリングのような振る舞いを指定するのに便利です。
異なるベースクラスを指定する場合は、クラスを controller メソッドに明示的に渡すことができます:
controller(BaseController)
基本的な型推論を無効にすることもできます。その場合、無名コントローラはデフォルトで述べられたクラスではなくApplicationControllerから継承するようになります:
RSpec.configure do |c|
  c.infer_base_class_for_anonymous_controllers = false
end
RSpec.describe BaseController, type: :controller do
  controller do
    def index; end
    # this normally creates an anonymous `BaseController` subclass,
    # however since `infer_base_class_for_anonymous_controllers` is
    # disabled, it creates a subclass of `ApplicationController`
  end
end
Specify error handling in ApplicationController with redirect
Given a file named "spec/controllers/application_controller_spec.rb" with:
require "rails_helper"
class ApplicationController < ActionController::Base
  class AccessDenied < StandardError; end
  rescue_from AccessDenied, :with => :access_denied
private
  def access_denied
    redirect_to "/401.html"
  end
end
RSpec.describe ApplicationController, type: :controller do
  controller do
    def index
      raise ApplicationController::AccessDenied
    end
  end
  describe "handling AccessDenied exceptions" do
    it "redirects to the /401.html page" do
      get :index
      expect(response).to redirect_to("/401.html")
    end
  end
end
When I run rspec spec
Then the examples should all pass.
Specify error handling in ApplicationController with render
Given a file named "spec/controllers/application_controller_spec.rb" with:
require "rails_helper"
class ApplicationController < ActionController::Base
  class AccessDenied < StandardError; end
  rescue_from AccessDenied, :with => :access_denied
private
  def access_denied
    render "errors/401"
  end
end
RSpec.describe ApplicationController, type: :controller do
  controller do
    def index
      raise ApplicationController::AccessDenied
    end
  end
  describe "handling AccessDenied exceptions" do
    it "renders the errors/401 template" do
      get :index
      expect(response).to render_template("errors/401")
    end
  end
end
When I run rspec spec
Then the examples should all pass.
Specify error handling in a subclass
Given a file named "spec/controllers/application_controller_subclass_spec.rb" with:
require "rails_helper"
class ApplicationController < ActionController::Base
  class AccessDenied < StandardError; end
end
class FoosController < ApplicationController
  rescue_from ApplicationController::AccessDenied,
              :with => :access_denied
private
  def access_denied
    redirect_to "/401.html"
  end
end
RSpec.describe FoosController, type: :controller do
  controller(FoosController) do
    def index
      raise ApplicationController::AccessDenied
    end
  end
  describe "handling AccessDenied exceptions" do
    it "redirects to the /401.html page" do
      get :index
      expect(response).to redirect_to("/401.html")
    end
  end
end
When I run rspec spec
Then the examples should all pass.
Infer base class from the described class
Given a file named "spec/controllers/base_class_can_be_inferred_spec.rb" with:
require "rails_helper"
class ApplicationController < ActionController::Base; end
class FoosController < ApplicationController; end
RSpec.describe FoosController, type: :controller do
  controller do
    def index
      render :plain => "Hello World"
    end
  end
  it "creates anonymous controller derived from FoosController" do
    expect(controller).to be_a_kind_of(FoosController)
  end
end
When I run rspec spec
Then the examples should all pass.
Use name and controller_name from the described class
Given a file named "spec/controllers/get_name_and_controller_name_from_described_class_spec.rb" with:
require "rails_helper"
class ApplicationController < ActionController::Base; end
class FoosController < ApplicationController; end
RSpec.describe "Access controller names", type: :controller do
  controller FoosController do
    def index
      @name = self.class.name
      @controller_name = controller_name
      render :plain => "Hello World"
    end
  end
  before do
    get :index
  end
  it "gets the class name as described" do
    expect(assigns[:name]).to eq('FoosController')
  end
  it "gets the controller_name as described" do
    expect(assigns[:controller_name]).to eq('foos')
  end
end
When I run rspec spec
Then the examples should all pass.
Invoke around_filter and around_action in base class
Given a file named "spec/controllers/application_controller_around_filter_spec.rb" with:
require "rails_helper"
class ApplicationController < ActionController::Base
  around_action :an_around_filter
  def an_around_filter
    @callback_invoked = true
    yield
  end
end
RSpec.describe ApplicationController, type: :controller do
  controller do
    def index
      render :plain => ""
    end
  end
  it "invokes the callback" do
    get :index
    expect(assigns[:callback_invoked]).to be_truthy
  end
end
When I run rspec spec
Then the examples should all pass.
Anonymous controllers only create resource routes
Given a file named "spec/controllers/application_controller_spec.rb" with:
require "rails_helper"
if defined?(ActionController::UrlGenerationError)
  ExpectedRoutingError = ActionController::UrlGenerationError
else
  ExpectedRoutingError = ActionController::RoutingError
end
RSpec.describe ApplicationController, type: :controller do
  controller do
    def index
      render :plain => "index called"
    end
    def create
      render :plain => "create called"
    end
    def new
      render :plain => "new called"
    end
    def show
      render :plain => "show called"
    end
    def edit
      render :plain => "edit called"
    end
    def update
      render :plain => "update called"
    end
    def destroy
      render :plain => "destroy called"
    end
    def willerror
      render :plain => "will not render"
    end
  end
  describe "#index" do
    it "responds to GET" do
      get :index
      expect(response.body).to eq "index called"
    end
    it "also responds to POST" do
      post :index
      expect(response.body).to eq "index called"
    end
    it "also responds to PUT" do
      put :index
      expect(response.body).to eq "index called"
    end
    it "also responds to DELETE" do
      delete :index
      expect(response.body).to eq "index called"
    end
  end
  describe "#create" do
    it "responds to POST" do
      post :create
      expect(response.body).to eq "create called"
    end
    # And the rest...
    %w{get post put delete}.each do |calltype|
      it "responds to #{calltype}" do
        send(calltype, :create)
        expect(response.body).to eq "create called"
      end
    end
  end
  describe "#new" do
    it "responds to GET" do
      get :new
      expect(response.body).to eq "new called"
    end
    # And the rest...
    %w{get post put delete}.each do |calltype|
      it "responds to #{calltype}" do
        send(calltype, :new)
        expect(response.body).to eq "new called"
      end
    end
  end
  describe "#edit" do
    it "responds to GET" do
      get :edit, :params => { :id => "anyid" }
      expect(response.body).to eq "edit called"
    end
    it "requires the :id parameter" do
      expect { get :edit }.to raise_error(ExpectedRoutingError)
    end
    # And the rest...
    %w{get post put delete}.each do |calltype|
      it "responds to #{calltype}" do
        send(calltype, :edit, :params => {:id => "anyid"})
        expect(response.body).to eq "edit called"
      end
    end
  end
  describe "#show" do
    it "responds to GET" do
      get :show, :params => { :id => "anyid" }
      expect(response.body).to eq "show called"
    end
    it "requires the :id parameter" do
      expect { get :show }.to raise_error(ExpectedRoutingError)
    end
    # And the rest...
    %w{get post put delete}.each do |calltype|
      it "responds to #{calltype}" do
        send(calltype, :show, :params => {:id => "anyid"})
        expect(response.body).to eq "show called"
      end
    end
  end
  describe "#update" do
    it "responds to PUT" do
      put :update, :params => { :id => "anyid" }
      expect(response.body).to eq "update called"
    end
    it "requires the :id parameter" do
      expect { put :update }.to raise_error(ExpectedRoutingError)
    end
    # And the rest...
    %w{get post put delete}.each do |calltype|
      it "responds to #{calltype}" do
        send(calltype, :update, :params =>  {:id => "anyid"})
        expect(response.body).to eq "update called"
      end
    end
  end
  describe "#destroy" do
    it "responds to DELETE" do
      delete :destroy, :params => { :id => "anyid" }
      expect(response.body).to eq "destroy called"
    end
    it "requires the :id parameter" do
      expect { delete :destroy }.to raise_error(ExpectedRoutingError)
    end
    # And the rest...
    %w{get post put delete}.each do |calltype|
      it "responds to #{calltype}" do
        send(calltype, :destroy, :params => {:id => "anyid"})
        expect(response.body).to eq "destroy called"
      end
    end
  end
  describe "#willerror" do
    it "cannot be called" do
      expect { get :willerror }.to raise_error(ExpectedRoutingError)
    end
  end
end
When I run rspec spec
Then the examples should all pass.
Draw custom routes for anonymous controllers
Given a file named "spec/controllers/application_controller_spec.rb" with:
require "rails_helper"
RSpec.describe ApplicationController, type: :controller do
  controller do
    def custom
      render :plain => "custom called"
    end
  end
  specify "manually draw the route to request a custom action" do
    routes.draw { get "custom" => "anonymous#custom" }
    get :custom
    expect(response.body).to eq "custom called"
  end
end
When I run rspec spec
Then the examples should all pass.
Draw custom routes for anonymous controllers which don't inherit from application controller
Given a file named "spec/controllers/other_controller_spec.rb" with:
require "rails_helper"
class OtherController < ActionController::Base
end
RSpec.describe OtherController, type: :controller do
  controller do
    def custom
      render :plain => "custom called"
    end
  end
  specify "manually draw the route to request a custom action" do
    routes.draw { get "custom" => "other#custom" }
    get :custom
    expect(response.body).to eq "custom called"
  end
end
When I run rspec spec
Then the examples should all pass.
Draw custom routes for defined controllers
Given a file named "spec/controllers/application_controller_spec.rb" with:
require "rails_helper"
class FoosController < ApplicationController; end
RSpec.describe ApplicationController, type: :controller do
  controller FoosController do
    def custom
      render :plain => "custom called"
    end
  end
  specify "manually draw the route to request a custom action" do
    routes.draw { get "custom" => "foos#custom" }
    get :custom
    expect(response.body).to eq "custom called"
  end
end
When I run rspec spec
Then the examples should all pass.
Works with namespaced controllers
Given a file named "spec/controllers/namespaced_controller_spec.rb" with:
require "rails_helper"
class ApplicationController < ActionController::Base; end
module Outer
  module Inner
    class FoosController < ApplicationController; end
  end
end
RSpec.describe Outer::Inner::FoosController, type: :controller do
  controller do
    def index
      @name = self.class.name
      @controller_name = controller_name
      render :plain => "Hello World"
    end
  end
  it "creates anonymous controller derived from the namespace" do
    expect(controller).to be_a_kind_of(Outer::Inner::FoosController)
  end
  it "gets the class name as described" do
    expect{ get :index }.to change{
      assigns[:name]
    }.to eq('Outer::Inner::FoosController')
  end
  it "gets the controller_name as described" do
    expect{ get :index }.to change{
      assigns[:controller_name]
    }.to eq('foos')
  end
end
When I run rspec spec
Then the examples should all pass.
Refer to application routes in the controller under test
Given a file named "spec/controllers/application_controller_spec.rb" with:
require "rails_helper"
Rails.application.routes.draw do
  match "/login" => "sessions#new", :as => "login", :via => "get"
end
RSpec.describe ApplicationController, type: :controller do
  controller do
    def index
      redirect_to login_url
    end
  end
  it "redirects to the login page" do
    get :index
    expect(response).to redirect_to("/login")
  end
end
When I run rspec spec
Then the examples should all pass.