【Rails6】 RSpec에 의한 Notification의 모델 단위 테스트의 구현

소개



서비스 품질을 유지하기 위해 필수적인 테스트를 실시하고 있습니다.
이번은 Notification(통지) 모델편이라고 하는 것으로, 향후 다른 모델에 대해서도 실시해 기사로 해 가고 싶습니다.

※notification 모델 이외의 기술에 관해서는 생략하고 있습니다.
나중에 알림 기능에 대한 기사를 올리기 위해 그 때 자세한 내용을 올립니다.

전제



· 다음 gem은 설치됨
  gem 'rspec-rails', '~> 4.0.0'
  gem 'factory_bot_rails'
  gem 'faker'

· 알림 기능 구현 완료

버전



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

실시한 테스트





notifications 테이블의 열 소개



xxx_create_notifications.rb
class CreateNotifications < ActiveRecord::Migration[6.0]
  def change
    create_table :notifications do |t|
      t.references :visitor, foreign_key:{ to_table: :users }, null: false
      t.references :visited, foreign_key:{ to_table: :users }, null: false

      t.references :definition, foreign_key: true
      t.references :answer, foreign_key: true

      t.string :action, null: false
      t.boolean :checked, null: false, default: false

      t.timestamps
    end
  end
end





● 위치 관계
답변 ← ← 좋아요
게시물 ← ← 리뷰

모델 내 어소시에이션



app/models/notification.rb
class Notification < ApplicationRecord
  default_scope -> { order(created_at: :desc) }
  belongs_to :visitor, class_name: "User", optional: true
  belongs_to :visited, class_name: "User", optional: true
  belongs_to :definition, optional: true
  belongs_to :answer, optional: true

end

FactoryBot의 내역



spec/factories/notifications.rb
FactoryBot.define do
  factory :notification do
  end
end

테스트 코드 내용



spec/models/notification_spec.rb
require 'rails_helper'

RSpec.describe Notification, type: :model do
  describe "#create" do
    context "Answer関連の通知" do
      before do
        @answer = FactoryBot.build(:answer)
        @definition = FactoryBot.build(:definition)
      end

      it "回答が行われた場合に保存できる" do
        notification = FactoryBot.build(:notification, answer_id: @answer.id, answer_id: @answer.id, action: "answer")
        expect(notification).to be_valid
      end

      it "投稿が行われた場合に保存できる" do
        notification = FactoryBot.build(:notification, definition_id: @definition.id, definition_id: @definition.id, action: "definition")
        expect(notification).to be_valid
      end

      it "回答にいいねが行われた場合に保存できる" do
        notification = FactoryBot.build(:notification, answer_id: @answer.id, action: "like")
        expect(notification).to be_valid
      end

      it "投稿にレビューが行われた場合に保存できる" do
        notification = FactoryBot.build(:notification, definition_id: @definition.id, action: "review")
        expect(notification).to be_valid
      end

    context "フォロー関連の通知" do
      it "フォローが行われた場合に保存できる" do
        user1 = FactoryBot.build(:user)
        user2 = FactoryBot.build(:user)
        notification = FactoryBot.build(:notification, visitor_id: user1.id, visited_id: user2.id, action: "follow")
        expect(notification).to be_valid
      end
    end

  end

  describe "アソシエーションのテスト" do
    let(:association) do
      described_class.reflect_on_association(target)
    end

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

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

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

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

    context "visitorとのアソシエーション" do
      let(:target) { :visitor }

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

    context "visitedとのアソシエーション" do
      let(:target) { :visited }

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


보충 설명



optional: true 정보



optional : true는 id가없는 객체를 만들 수 있다는 의미가 있습니다.

디폴트로 id를 가지지 않는 오브젝트는 작성할 수 없기 때문에, optional: true를 붙이는 것으로, id를 가지지 않아도 오브젝트를 작성할 수 있도록(듯이) 하고 있습니다.

테스트 코드의 내용에 대해



・전체상으로서는, 액션(투고, 회답, 좋아, 리뷰, 팔로우)이 행해지면 통지가 행해져, 통지 정보가 보존되는 구조입니다.

그래서 액션에 묶는 정상계를 테스트하고 있습니다.

· 어소시에이션이 짜고 있는지의 테스트도 실시하고 있습니다.

이상입니다.

좋은 웹페이지 즐겨찾기