Rspecについて勉強したときのメモです。
今回はrequest specについて!
#request specとは?
リクエストスペックはコントローラのテストのこと。
リクエストに対するレスポンスを確認することをテストします。
実装
テストの基本の流れは、
①確認したいことを決める
②ダミーデータを作成する
③ダミーデータで①の確認したいことが起こるかどうかを確認する
です。
これをrequest specに当てはめると、
①Getなどのリクエストを送って200や正しいレスポンスが返ってくるかを確認したい
②実際にリクエストを送る
③200ステータス、レスポンスの確認
という感じです。
では流れが分かったのでコードベースでやっていきます。
今回テストするサンプルアプリは前回のmodel spec同様User
がtitle
とcontent
カラムを持つArticle
モデルを投稿できるシンプルなものです。
factory_bot
factory_botでダミーデータを用意します。
gem 'factory_bot_rails'
bundle install
config.include FactoryBot::Syntax::Methods
これでインストールと設定完了。
ダミーデータを記述するフォルダとファイルを用意し、
mkdir spec/factories
touch spec/factories/users.rb
touch spec/factories/articles.rb
ここにダミーデータを書きます。
用意したいダミーデータはUser
モデルのデータとArticle
モデルのデータです。
記述の仕方は以下のとおり
faker
を使ってるので簡潔にかけます!
FactoryBot.define do
factory :user do
email { Faker::Internet.email }
password { 'password' }
end
end
FactoryBot.define do
factory :article do
title { Faker::Lorem.characters(number: 10) }
content { Faker::Lorem.characters(number: 50) }
end
end
これでダミーデータの準備完了。
Getリクエスト
それではテストしていきます。
今回テストするのはコントローラーのこの部分。
def index
@articles = Article.all
end
テストファイルを作成。
rails g rspec:request article
以下のファイルが出来てたらOK。
require 'rails_helper'
RSpec.describe 'Articles', type: :request do
describe 'GET /articles' do
it '200ステータスが返ってくる' do
get articles_path
expect(response).to have_http_status(200)
end
end
end
今回のgetリクエストでテストしたいことはindex actionをしたときにhttpステータスのレスポンスが正しい値(200)として返ってくるのかです。
なのでダミーデータとして必要なのはUser
と複数のArticle
ですね。
factory_botではcreate_list
を使うことでダミーデータを複数作ることができます。
ダミーデータを記述します。
RSpec.describe 'Articles', type: :request do
let!(:user) { create(:user) }
let!(:articles) { create_list(:article, 3, user: user) }
describe 'GET /articles' do
it '200ステータスが返ってくる' do
get articles_path
expect(response).to have_http_status(200)
end
end
あとはターミナルでテストが通るか確認してテストが通ればOK。
bundle exec rspec spec/requests/article_spec.rb
.
Finished in 0.01966 seconds (files took 1.02 seconds to load)
1 example, 0 failures
無事成功
Postリクエスト
次は同じPostリクエストです。
テストするコントローラーは以下の部分
def create
@article = current_user.articles.build(article_params)
if @article.save
redirect_to article_path(@article), notice: '保存できました'
else
flash.now[:error] = '保存に失敗しました'
render :new
end
end
ここでテストすることは、記事が正しく保存されるかです。
とりあえず実装した部分
describe 'POST /articles' do
before do
sign_in user
end
it '記事が保存される' do
article_params = attributes_for(:article)
post articles_path({article: article_params})
expect(response).to have_http_status(302)
expect(Article.last.title).to eq(article_params[:title])
expect(Article.last.content.body.to_plain_text).to eq(article_params[:content])
end
end
###解説
記事を保存できるのはcurrent_user
だけなのでテストの前にログインしていることをbofore
で定義しています。
context 'ログインしている場合' do
before do
sign_in user
end
end
postするためには記事をパラメーターで渡すので、
factory_botで用意されているattributes_for
というメソッドを使えば記事のデータをパラメータにすることができます。
article_params = attributes_for(:article)
post articles_path({article: article_params})
記事保存後にリダイレクトしているので返ってくるhttpステータスは302
保存されたtitle
とcontent
の値がパラメーターの値と一致していれば正しく保存されていることを確認できる。
expect(response).to have_http_status(302)
expect(Article.last.title).to eq(article_params[:title])
expect(Article.last.content).to eq(article_params[:content])
これでテスト実行
bundle exec rspec spec/requests/article_spec.rb
.
Finished in 0.72662 seconds (files took 1.02 seconds to load)
1 example, 0 failures
通ればOK
以上です。