【Rails6】 RSpecによるReviewのモデル単体テストの実装


はじめに

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

今回はReviewモデル編ということで、今後他のモデルについても実施し記事にしていきたいと思います。

※レビューが何かについては以下「レビュー画面」でご確認いただけます。

前提

・以下のgemはインストール済み

  gem 'rspec-rails', '~> 4.0.0'
  gem 'factory_bot_rails'
  gem 'faker'

・レビュー機能実装済み

バージョン

rubyのバージョン 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/models/review_spec.rb
require 'rails_helper'

RSpec.describe Review, type: :model do
  before do
    @review = FactoryBot.build(:review)
  end
  describe '正常値と異常値の確認' do
    context 'reviewモデルのバリデーション' do
      it "user_idとdefinition_idがあれば保存できる" do
        expect(FactoryBot.create(:definition)).to be_valid
      end

      it"スコアがなければ保存できない"do
        @review.score = nil
        @review.valid?
        expect(@review.errors[:user_id]).to include("を入力してください")
      end

      it "user_idがなければ無効な状態であること" do
        @review.user_id = nil
        @review.valid?
        expect(@review.errors[:user_id]).to include("を入力してください")
      end

      it "definition_idがなければ無効な状態であること" do
        @review.definition_id = nil
        @review.valid?
        expect(@review.errors[:definition_id]).to include("を入力してください")
      end
    end
  end

    describe "各モデルとのアソシエーション" do
    let(:association) do
      described_class.reflect_on_association(target)
    end

    context "Userモデルとのアソシエーション" do
      let(:target) { :user }

      it "Userとの関連付けはbelongs_toであること" do
        expect(association.macro).to  eq :belongs_to
      end
    end

    context "Definitionモデルとのアソシエーション" do
      let(:target) { :definition }

      it "Definitionとの関連付けはbelongs_toであること" do
        expect(association.macro).to  eq :belongs_to
      end
    end
  end

end

補足説明

テストコードの内容について

・各バリデーションに従い、正常値と異常値を確認
・アソシエーションのテスト

以上です。