1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

ApplicationControllerでは、ユーザーのロール(役割)に対して、アクセス制御を行っていると思います。
では、そのアクセス制御をテストしようと思った時に、どのように実装しますでしょうか?

  • requestテストでやろう!
    • でも、ApplicationControllerへのルーティングは通っていないよね...
  • アクセス制御をしている箇所をConcernに切り分けて、単体テストでやろう!
    • これは結構良さげ
    • ただ、切り分けるほどの処理の大きさでもない...

上記のように、色々と模索すると思います。
その中で、AnonymousControllerを使用すれば、実装を変えずにテストすることができます。

今回はその内容をアウトプットいたします。

Rails5からは、request specが推奨されています。
今からは、controller specになるので、ご了承ください。

AnonymousController とは

controllerメソッドを使用して、匿名コントローラーを作成することができます。
明示的にコントローラーを渡すこともできますし、ルーティングも自動に設定してくれます。

実装

require 'rails_helper'

RSpec.describe ApplicationController, type: :controller do
  controller(ApplicationController) do
    def index
      render plain: "OK"
    end
  end

  describe '#authorize_access' do
    before do
      sign_in test_user
    end

    subject { get :index }

    context 'when the user has permission' do
      let(:test_user) { create(:test_user, role: 'editor') }

      it 'returns http success' do
        is_expected.to have_http_status(:success)
      end
    end
  end
end

解説

今回の例では、ApplicationControllerbefore_actionで定義しているメソッドをテストしています。(※ アクセス制御の部分)

get :indexを実行すると、実際のApplicationControllerを実行してくれます。
なので、すごくテストがしやすいです。

以下にも、解説や注意点をまとめました。

type: :controllerは忘れずに

ここを、type: :requestにしていると、controllerメソッドは使用できません。
typeは、controllerを必ず指定しましょう。

ルーティングは自動で設定される

controllerメソッドを使用して、匿名コントローラーを作成しているので、ルーティングの設定が必要になるかと思っていました。
ただ、親切に、AnonymousControllerは、自動で設定してくれます。
※ 明示的に、ルーティングの設定を記載しても問題ありません。

今回だと、indexメソッドを用意したので、get :indexと実装すれば、通るようになります。

controllerへの引数を渡すこともできる

今回はdescribeで指定しているコントローラーと差異はないので、controller(...)と引数を渡さなくても、問題ないかと思います。
ただ、明示的に渡して、特定のコントローラーで実装することも可能です。

Deviseの設定は、rails_helperに忘れずに (※ この記事限定)

今回の実装例では、sign_inメソッドを使用しています。
これは、Deviseのヘルパーメソッドになるので、controller specで使用できるように、設定が必要になります。

spec / rails_helper.rb
config.include Devise::Test::ControllerHelpers, type: :controller

上記を忘れずに設定しましょう。

まとめ

実装始めは、typerequestにしていて、controllerメソッドが使用できず、悪戦苦闘していました...。
ただ、実際に使用してみて、ApplicationControllerのテストには、すごく向いているなと思いました。

他のコントローラーのテストは、request specで十分です。
今回は、AnonymousControllerで実装しましたが、他にも良い実装があれば、教えていただきたいです。

最後までご覧いただき、ありがとうございました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?