RSpecのcontorollerテストとして、request specを使ってテストを実行していきます。
#開発環境
ruby 2.6.3
Rails 5.2.6
#前提
- FactoryBot使用
- Faker使用
- capybara使用
- devise使用
RSpecの準備、FactoryBotでのテストデータの定義等は、下記記事にまとめてますので、まだの方は先にこちらをどうぞ。
[Rails]RSpecでテストを行う準備(FactoryBot使用)
#request specとは
おもに、contorollerのテストで、URLのリクエストがちゃんと通るのかテストを実施していきます。
#ファイルの作成
まずは、spec配下に各コントローラーのファイルを作っていきます。
今回は、
posts_spec.rb
contacts_spec.rb
を作っていきます。
作成した各モデルのファイルで、rails_helperの設定を読み込んでいきます。
rails_helperはRSpecの設定が記述してあるファイルです。
コードを1行書くだけで、読み込めるので先に記述しておきます。
最初にまとめて書いておくことで、書き忘れを防げます!
require 'rails_helper'
#deviseのヘルパーを使えるようにする
controllerのテストを実行していく中で、sign_inなどのdeviseのヘルパーを使う機会が出てきます。
なぜRSpecのコードを書いていくときに、deviseのヘルパーが必要かというと、アクセス権限でログインしてないユーザーを許可していない場合があるから
です。
ユーザーの編集ページはログインしてないときは、アクセスできないなど
spec/rails_helper.rb
にdeviseのヘルパーを使えるようにコードを追加します。
:
# deviseのヘルパーメソッドをrequestsで使用できるように設定
config.include Devise::Test::IntegrationHelpers, type: :request
end
これでdeviseのヘルパーをrequestsで使用できるようになりました。
#テストコードを書いていく
各コントローラーごとにテストコードを書いていきます。
今回テストするコントローラーの各アクションは、以下の通りです。
controller | action |
---|---|
posts | new, index, show |
contacts | new,confirm,complete |
基本形はこうです。
it "returns http success" do
# アクセス制限しているところなら
sign_in
# URLリクエストを通す
HTTPメソッド パス名
# リクエストが通ったか確認
expect(response).to have_http_status(:success)
end
####posts controller
posts controllerのnewとshowアクションでは、ログインしていないユーザーはアクセスできないようにしてあるので、sign_inヘルパーを使用します。
require 'rails_helper'
RSpec.describe "Posts", type: :request do
# FactoryBotのテストデータを使ってuserとpostのデータを作成
let!(:user) { create(:user) }
let!(:post) { create(:post, user_id: user.id) }
describe "GET /new" do
it "returns http success" do
sign_in user
get new_post_path
expect(response).to have_http_status(:success)
end
end
describe "GET /index" do
it "returns http success" do
get posts_path
expect(response).to have_http_status(:success)
end
end
describe "GET /show" do
it "returns http success" do
sign_in user
get post_path(post)
expect(response).to have_http_status(:success)
end
end
end
####contacts controller
contacts controllerでは、アクセス制限をしていないので、sign_inヘルパーは使いません。
confirmアクションがnewアクションからformで値を受け取る形なので、HTTPメソッドがPOSTになってます。
require 'rails_helper'
RSpec.describe "Contacts", type: :request do
describe "GET /new" do
it "returns http success" do
get "/contacts/new"
expect(response).to have_http_status(:success)
end
end
# POSTになっている
describe "POST /confirm" do
it "returns http success" do
# newアクションから送られてきた値をもたせてあげる
post confirm_contacts_path, params: { contact: { name: 'test', email: 'a@a', content: 'content sample' } }
expect(response).to have_http_status(:success)
end
end
describe "GET /complete" do
it "returns http success" do
get "/contacts/complete"
expect(response).to have_http_status(:success)
end
end
end
confirm以外は基本形の書き方で問題ないです。
#テストを実行
requests specのテストを実行します。
$ bundle exec rspec spec/requests
ターミナル結果に6 examples, 0 failures
があれば、テスト成功です。
#まとめ
URLのリクエストが通るかは重要なテスト項目になりますので、参考にしてテストコードを書いてみてください。
他にもRSpecに関する記事書いてますので、よかったらどうぞ!
[Rails]RSpecでテストを行う準備(FactoryBot使用)
[Rails]RSpecでモデルのテスト(FactoryBot使用)
[Rails]RSpecでよく使うマッチャー10選