4
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?

More than 3 years have passed since last update.

【Rails6】RSpecによるいいね機能の結合テストの実装

Last updated at Posted at 2021-03-09

#はじめに
サービスの品質を保つために必要不可欠なテストを実施しております。

今回はいいね機能の結合テストを実装し、その実装内容を記事にしていきたいと思います。

#前提
・Like(いいね)モデルの単体テストは実施済み

※完了されていない方や単体テストと並行してご覧になられたい方は、以下のLikeモデルの単体テストについての記事をご参考ください。

#バージョン
rubyのバージョン ruby-2.6.5
Railsのバージョン Rails:6.0.0
rspec-rails 4.0.0

#実施したテスト
image.png

#likesテーブルのカラムの紹介

xxx_create_likes.rb
class CreateLikes < ActiveRecord::Migration[6.0]
  def change
    create_table :likes do |t|
      t.references :user,       foreign_key: true
      t.references :answer,     foreign_key: true
      t.references :definition,     foreign_key: true
      t.timestamps
    end
  end
end

image.png

#「いいね」に関するviewの内容

app/views/definitions/show.html.erb

# 〜省略〜 

 <% if current_user.already_liked?(answer) %>

    <%= link_to definition_answer_likes_path(@definition,answer), method: :delete do %>
      <i class="fas fa-heart", id="liking-btn"></i>
    <% end %>
                  
<% else %>
    <%= link_to definition_answer_likes_path(@definition,answer), method: :post do %>
      <i class="far fa-heart", id="nolike-btn"></i>
    <% end %>

 <% end %>
                 
 <%= answer.likes.count %>
 <%= "(#{time_ago_in_words(answer.created_at)}前)" %> 

# 〜省略〜

#モデル内のバリデーション

app/models/like.rb
class Like < ApplicationRecord
  belongs_to :user
  belongs_to :answer
  belongs_to :definition

  validates :user_id, presence: true
  validates :answer_id, uniqueness: { scope: :user_id }, presence: true
  validates :definition_id, uniqueness: { scope: :user_id }, presence: true
end

#FactoryBotの内訳

spec/factories/likes.rb
FactoryBot.define do
  factory :like do
    association :answer
    association :definition
    user { answer.user }
  end
end

#サポートモジュール

spec/support/sign_in_support.rb
module SignInSupport
  def sign_in(user)
    visit user_session_path
    fill_in 'user[email]', with: user.email
    fill_in 'user[password]', with: user.password
    find('input[name="commit"]').click
    expect(current_path).to eq(root_path)
  end
end

#テストコードの内容

spec/system/likes_spec.rb
require 'rails_helper'

RSpec.describe "Likes", type: :system do
    before do
      @definition = FactoryBot.create(:definition)
      @answer = FactoryBot.create(:answer)
    end

    describe '#create,#destroy' do
      it 'ユーザーが他の投稿をいいね、いいね解除できる' do
        # ログインする
        sign_in(@definition.user)
          
        # 投稿詳細ページに遷移する
        visit definition_path(@definition.id)
          
        # フォームに情報を入力する
        fill_in 'answer_answer', with: @answer
          
        # 回答を送信すると、Answerモデルのカウントが1上がることを確認する
        expect{
          find('input[name="commit"]').click
        }.to change { Answer.count }.by(1)
          
        # いいねをするボタンを押す
        find('#nolike-btn').click
        expect(page).to have_selector '#liking-btn'
        expect(@answer.likes.count).to eq(1)

        # いいねを解除する
        find('#liking-btn').click
        expect(page).to have_selector '#nolike-btn'
        expect(@answer.likes.count).to eq(0)
        end
     end
end

#補足説明
##find().clickについて
今回、引数の値はview内のいいねボタンのidの要素となります。

app/views/definitions/show.html.erb

# 〜省略〜 

      <i class="fas fa-heart", id="liking-btn"></i>

# 〜省略〜 

      <i class="far fa-heart", id="nolike-btn"></i>

# 〜省略〜 

##have_selectorについて

have_selector 〜の〜内に特定の要素を含んでいるか検査します。

なので、

spec/system/likes_spec.rb
expect(page).to have_selector '#liking-btn'

pageでvisitで訪れた先のページのことで、そのページ内にliking-btnのidの要素を含んでいるかの確認をしています。

#expect( ).to eq( )について
AnswerモデルとLikeモデルはアソシエーションで紐付けているので

spec/system/likes_spec.rb
expect(@answer.likes.count).to eq(1)

likesテーブル内のカラムのcount数は1となるという意味になります。

以上です。

4
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
4
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?