【Rails】RSpecによるテスト 3.コントローラーのテスト


RSpecを使ったコントローラーのテスト

今回はコントローラーの単体テストを行っていきます。
コントローラーのテストで確認したい点は大きく2つで、

  • 定義しているインスタンス変数が思ったものになっているか
  • アクションの後に思ったビューが表示されるか

となります。
例として、ブログのposts_controllerのeditアクションについてテストを行います。
posts_controller内のeditアクションについての記述は以下の通りです。

posts_controller.rb
  def edit
    @post = Post.find(params[:id])
  end

編集する元の記事をインスタンス変数に定義しています。
すなわち、今回のテストで行うことは@postが正しく定義されているかと、アクションの結果editビューが呼び出されるかどうかの2つとなります。

factory_botの設定

まずはfactory_botを設定してpostの生成をする準備を行います。

spec/factories/post.rb
FactoryBot.define do
  factory :post do
    title { Faker::Food.dish }
    text { Faker::Food.fruits }
    user
  end
end

タイトルと本文の決め方は正直適当です。emailのように重複してもエラーは出ないので、Fakerを使わず直接値を入力しても問題ないと思います。

コントローラーのテストを実行

factory_botの準備ができたらテストを実行していきます。

spec/controller/posts_controller_spec.rb
require 'rails_helper'

describe PostsController do
  describe 'GET #edit' do

    it "assigns the requested post to @post" do
      post = create(:post)
      get :edit, params: { id: post }
      expect(assigns(:post)).to eq post
    end

    it "renders the :edit template" do
      post = create(:post)
      get :edit, params: { id: post }
      expect(response).to render_template :edit
    end
  end
end

モデルのテストと違ってくる点は、

  • buildではなくcreateを使用
    今回は保存したpostの呼び出しを行えるかテストをするため、作成したpostデータをテーブルに保存するためcreateメソッドを用います。

  • assigns(:〜)
    アクション内で定義されたインスタンス変数をシンボル型で指定します。
    この書き方で、 @post は post と同じかどうかを確認します。

テストの結果を確認します。
bundle exec rspecでもテスト結果は確認できますが、他のテストも同時に実行されます。
今回のテスト結果のみを確認する場合は、ターミナルで実行するテストファイルを指定します。

ターミナル
$ bundle exec rspec spec/controllers/posts_controller_spec.rb
ターミナル
PostsController
  GET #edit
    assigns the requested post to @post
    renders the :edit template

Finished in 0.35048 seconds (files took 2.88 seconds to load)
2 examples, 0 failures

テストの結果は問題ないようです。