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

소개



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

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

전제



・리뷰 기능은 실장 완료
・Review(리뷰) 모델의 단위 테스트는 실시 완료

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

버전



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

실시한 테스트





리뷰 화면





reviews 테이블의 열 소개



xxx_create_reviews.rb
class CreateReviews < ActiveRecord::Migration[6.0]
  def change
    create_table :reviews do |t|
      t.string :content
      t.integer :score
      t.references :user,       foreign_key: true
      t.references :definition, foreign_key: true
      t.timestamps
    end
  end
end

모델 내 검증



app/models/review.rb
class Review < ApplicationRecord
  belongs_to :user
  belongs_to :definition

  validates :user_id, presence: true
  validates :definition_id, presence: true
  validates :score, presence: true
  validates_uniqueness_of :definition_id, scope: :user_id
end

FactoryBot의 내역



spec/factories/reviews.rb
FactoryBot.define do
  factory :review do
    association :definition
    association :user
    content                       {Faker::Lorem.word}
    score                         {'3'}
  end
end

지원 모듈



spec/support/review_up_support.rb
module ReviewUpSupport
  def review_up(review)
  # レビュー作成ページに遷移する
  visit new_definition_review_path(@definition)

  # レビューの存在の確認
  expect(page).to have_selector '#star1'
  expect(page).to have_selector '#star2'
  expect(page).to have_selector '#star3'
  expect(page).to have_selector '#star4'
  expect(page).to have_selector '#star5'

  # 星マークにカーソルを合わた場所でクリックする(今回は3段階)
  expect(find('#star3').hover.click)

  # レビューのコメントに情報を入力する
  fill_in 'review[content]', with: review.content

  # レビューのコメントを送信すると、Reviewモデルのカウントが1上がることを確認する
  expect{
    find('input[name="commit"]').click
  }.to change { Review.count }.by(1)
  end
end

테스트 코드 내용



spec/system/reviews_spec.rb
require 'rails_helper'

RSpec.describe "Reviews", type: :system, js: true do
  before do
    @definition = FactoryBot.create(:definition)
    @review = FactoryBot.create(:review)
  end
    describe '#create,#destroy' do
      context 'レビューができるとき' do
        it 'ユーザーが投稿に対してレビューができる' do
        # ログインする
        sign_in(@definition.user)

        #新規レビューを作成する
        review_up(@review)

        # # レビュー詳細ページに遷移する
        visit definition_reviews_path(@definition)

        # レビュー詳細ページにてレビューした投稿があることを確認する
        expect(page).to have_content(@review.score)
        expect(page).to have_content(@review.content)
        end
      end

      context 'レビューができないとき' do
        it 'ユーザーが投稿に対してレビューをすでにしており、レビューができない' do
         # ログインする
         sign_in(@definition.user)

         # レビュー作成ページに遷移する
         visit new_definition_review_path(@definition)

         #新規レビューを作成する
         review_up(@review)

         # レビュー作成ページに遷移する
         visit new_definition_review_path(@definition)

         # 星マークにカーソルを合わた場所でクリックする(今回は3段階)
         expect(find('#star3').hover.click)

         # レビューのコメントに情報を入力する
         fill_in 'review[content]', with: @review.content

         # レビューのコメントを送信すると、Reviewモデルのカウントが上がらないことを確認する
         expect{
          find('input[name="commit"]').click
        }.to change { Review.count }.by(0)

        # レビューページへ戻されることを確認する
         expect(current_path).to eq(definition_reviews_path(@definition))
        end
      end
   end
end

보충 설명



#star 정보



별 마크를 기술하고 있는 뷰내의 id이며, 이번에는 5개 있습니다.
테스트의 관계상 id를 구별할 필요가 있었기 때문에 번부하고 있습니다.

app/views/reviews/index.html.erb
# 〜省略〜
      <span class="fa fa-star-o" id="star1"></span>
      <span class="fa fa-star-o" id="star2"></span>
      <span class="fa fa-star-o" id="star3"></span>
      <span class="fa fa-star-o" id="star4"></span>
      <span class="fa fa-star-o" id="star5"></span>
# 〜省略〜

'#'을 문장에 붙이면 id를 가리킬 수 있습니다.

비정상적인 시스템의 Review.count 정보



모델 내에 uniquness의 밸리데이션을 걸고 있어, 리뷰는 1회 밖에 할 수 없는 사양으로 하고 있습니다.

app/models/review.rb
validates_uniqueness_of :definition_id, scope: :user_id

따라서 한 번 검토하고 다시 검토해도 리뷰 카운트는 올라가지 않고 0 그대로를 증명할 수 있으면 리뷰를 할 수 없다는 것을 말할 수 있습니다.

이상입니다.

좋은 웹페이지 즐겨찾기