1
1

More than 1 year has passed since last update.

[Rails] Rspec基礎 factory_bot〜request spec

Last updated at Posted at 2021-09-30

Rspecについて勉強したときのメモです。
今回はrequest specについて!

request specとは?

リクエストスペックはコントローラのテストのこと。
リクエストに対するレスポンスを確認することをテストします。

実装

テストの基本の流れは、
①確認したいことを決める
②ダミーデータを作成する
③ダミーデータで①の確認したいことが起こるかどうかを確認する
です。

これをrequest specに当てはめると、
①Getなどのリクエストを送って200や正しいレスポンスが返ってくるかを確認したい
②実際にリクエストを送る
③200ステータス、レスポンスの確認
という感じです。

では流れが分かったのでコードベースでやっていきます。
今回テストするサンプルアプリは前回のmodel spec同様Usertitlecontentカラムを持つArticleモデルを投稿できるシンプルなものです。

factory_bot

factory_botでダミーデータを用意します。

Gemfile
gem 'factory_bot_rails'
ターミナル
bundle install
spec/rails_helper.rb
config.include FactoryBot::Syntax::Methods

これでインストールと設定完了。

ダミーデータを記述するフォルダとファイルを用意し、

ターミナル
mkdir spec/factories
touch spec/factories/users.rb
touch spec/factories/articles.rb

ここにダミーデータを書きます。

用意したいダミーデータはUserモデルのデータとArticleモデルのデータです。
記述の仕方は以下のとおり
fakerを使ってるので簡潔にかけます!

spec/factories/users.rb
FactoryBot.define do
  factory :user do
    email { Faker::Internet.email }
    password { 'password' }
  end
end
spec/factories/articles.rb
FactoryBot.define do
  factory :article do
    title { Faker::Lorem.characters(number: 10) }
    content { Faker::Lorem.characters(number: 50) }
  end
end

これでダミーデータの準備完了。

Getリクエスト

それではテストしていきます。

今回テストするのはコントローラーのこの部分。

app/controller/articles_controller.rb
def index
 @articles = Article.all
end

テストファイルを作成。

ターミナル
rails g rspec:request article

以下のファイルが出来てたらOK。

requests/articles_spec.rb
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を使うことでダミーデータを複数作ることができます。
ダミーデータを記述します。

requests/articles_spec.rb
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リクエストです。
テストするコントローラーは以下の部分

app/controller/articles_controller.rb
 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

ここでテストすることは、記事が正しく保存されるかです。
とりあえず実装した部分

requests/articles_spec.rb
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
保存されたtitlecontentの値がパラメーターの値と一致していれば正しく保存されていることを確認できる。

 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

以上です。

1
1
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
1