【Rails6】RSpec에 의한 좋아 기능의 결합 테스트의 구현

소개



서비스 품질을 유지하기 위해 필수적인 테스트를 실시하고 있습니다.

이번에는 좋아하는 기능의 결합 테스트를 구현하고 그 구현 내용을 기사로 해 나가고 싶습니다.

전제



・Like(좋아) 모델의 단위 테스트는 실시 완료

※완료되어 있지 않은 분이나 단체 테스트와 병행해 보시고 싶은 분은, 이하의 Like 모델의 단체 테스트에 대한 기사를 참고해 주세요.

버전



루비 버전 ruby-2.6.5
Rails 버전 Rails:6.0.0
rspec-rails 4.0.0

실시한 테스트





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



「좋아요」에 관한 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이 된다는 의미가 됩니다.

이상입니다.

좋은 웹페이지 즐겨찾기