はじめに
サービスの品質を保つために必要不可欠なテストを実施しております。
今回は投稿時のモデル(Definitionモデル)単体テストを行い、その内容を記事にしました。
今後他のモデルについても実施し記事にしていきたいと思います。
またテストは追加で行って参りますので、今後も投稿時のモデル単体テストの内容を追加していきます。
前提
・以下の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
実施したテスト
definitionsテーブルのカラムの紹介
xxx_create_definitions.rb
class CreateDefinitions < ActiveRecord::Migration[6.0]
def change
create_table :definitions do |t|
t.text :title, null: false
t.text :body, null: false
t.references :user, foreign_key: true
t.timestamps
end
end
end
モデル内のアソシエーションとバリデーション
app/models/definition.rb
class Definition < ApplicationRecord
belongs_to :user
has_many :answers, dependent: :destroy
has_many :reviews, dependent: :destroy
has_many :notifications, dependent: :destroy
has_many :likes, dependent: :destroy
validates :title, presence: true
validates :body, presence: true
# 〜省略〜
FactoryBotの内訳
spec/factories/definitions.rb
FactoryBot.define do
factory :definition do
title {Faker::Lorem.sentence}
body {Faker::Lorem.sentence}
association :user
end
end
テストコードの内容
spec/models/definition_spec.rb
require 'rails_helper'
RSpec.describe Definition, type: :model do
before do
@definition = FactoryBot.build(:definition)
end
describe '投稿' do
context '投稿がうまくいくとき' do
it "内容に問題ない場合" do
expect(@definition).to be_valid
end
it "正しく保存できるか" do
expect(FactoryBot.build(:definition)).to be_valid
end
end
context '投稿が上手くいかないとき' do
it "titleが空だと登録できない" do
@definition.title = ''
@definition.valid?
expect(@definition.errors.full_messages).to include("Titleを入力してください")
end
it "bodyが空だと登録できない" do
@definition.body = ''
@definition.valid?
expect(@definition.errors.full_messages).to include("Bodyを入力してください")
end
end
end
describe "各モデルとのアソシエーション" do
let(:association) do
described_class.reflect_on_association(target)
end
let(:definition) { FactoryBot.create(:definition) }
context "Likeモデルとのアソシエーション" do
let(:target) { :likes }
it "Likeとの関連付けはhas_manyであること" do
expect(association.macro).to eq :has_many
end
it "Defintionが削除されたらLikeも削除されること" do
like = FactoryBot.create(:like, definition_id: definition.id)
expect { definition.destroy }.to change(Like, :count).by(-1)
end
end
context "Answerモデルとのアソシエーション" do
let(:target) { :answers }
it "Answerとの関連付けはhas_manyであること" do
expect(association.macro).to eq :has_many
end
it "Definitionが削除されたらAnswerも削除されること" do
answer = FactoryBot.create(:answer, definition_id: definition.id)
expect { definition.destroy }.to change(Answer, :count).by(-1)
end
end
end
end
以上です。