0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rails: モデルの作成からRSpecテストまでの流れをまとめてみた

Posted at

はじめに

Docker環境でのRailsによる開発でモデル作成、RSpecによるテストの実行の流れを備忘録として残しておきます。

フロントエンドとバックエンドを分けて開発しているのでそれに沿ったコマンドになっているのでご了承ください。

環境

  • Ruby 3.2.9
  • Rails 7.1.0
  • RSpec 6.1
  • FactoryBot 6.4

今回実装するCountryテーブルのER図

image.png

1. マイグレーションファイルの作成

まず、Countryテーブルを作成するマイグレーションファイルを生成します。

docker-compose exec backend rails generate migration CreateCountries

生成されたマイグレーションファイル (db/migrate/timestamp_create_countries.rb) を編集:

class CreateCountries < ActiveRecord::Migration[7.1]
  def change
    create_table :countries do |t|
      t.string :name, null: false
      t.string :hint_1
      t.string :hint_2
      t.string :hint_3
      t.string :hint_4
      t.string :flag_url

      t.timestamps
    end
  end
end

マイグレーションの実行

docker-compose exec backend rails db:migrate

これで countries テーブルがデータベースに作成されます。

2. モデルファイルの作成

docker-compose exec backend rails generate model Country --skip-migration
  • --skip-migration オプションを付けることで、既に作成済みのマイグレーションファイルと重複しないようにします。テーブルが重複しなければつける必要はありません。

筆者はこのオプションを忘れたため実行後に新しいマイグレーションファイルが自動生成され、既存の テーブル と重複してしまいました。その結果、マイグレーションを実行すると同じテーブルやカラムを二重に作ろうとしてエラーが発生しました。

生成された app/models/country.rb にバリデーションとアソシエーションを追加:

class Country < ApplicationRecord
  # アソシエーション
  has_many :quiz_attempts, dependent: :destroy
  has_many :user_flags, dependent: :destroy
  has_many :users, through: :user_flags

  # バリデーション
  validates :name, presence: true, uniqueness: true
  validates :hint_1, presence: true
  validates :hint_2, presence: true
  validates :hint_3, presence: true
  validates :hint_4, presence: true
  validates :flag_url, presence: true
end

バリデーションの説明

  • name: 必須かつ一意
  • hint_1 ~ hint_4: すべて必須
  • flag_url: 必須

3. FactoryBotファクトリーの定義

rails generate model コマンドで自動生成された spec/factories/countries.rb を編集:

FactoryBot.define do
  factory :country do
    sequence(:name) { |n| "Test Country #{n}" }
    hint_1 { "This is hint 1" }
    hint_2 { "This is hint 2" }
    hint_3 { "This is hint 3" }
    hint_4 { "This is hint 4" }
    flag_url { "https://flagcdn.com/w320/jp.png" }
  end
end

ポイント

  • sequence(:name) で名前の重複を防ぐ
  • すべての必須項目にデフォルト値を設定

4. RSpecテストファイルの作成

spec/models/country_spec.rb を編集:

require 'rails_helper'

RSpec.describe Country, type: :model do
  describe 'associations' do
    it { should have_many(:quiz_attempts).dependent(:destroy) }
    it { should have_many(:user_flags).dependent(:destroy) }
    it { should have_many(:users).through(:user_flags) }
  end

  describe 'validations' do
    subject { create(:country) }

    it { should validate_presence_of(:name) }
    it { should validate_uniqueness_of(:name) }
    it { should validate_presence_of(:hint_1) }
    it { should validate_presence_of(:hint_2) }
    it { should validate_presence_of(:hint_3) }
    it { should validate_presence_of(:hint_4) }
    it { should validate_presence_of(:flag_url) }
  end

  describe 'factory' do
    it '有効なファクトリを持つこと' do
      expect(build(:country)).to be_valid
    end
  end
end

テストの構成

  1. associations: アソシエーションの存在確認
  2. validations: バリデーションルールの検証
  3. factory: テスト用データが存在するか確認

5. テストの実行

Countryモデルのテストを実行

docker-compose exec backend rspec spec/models/country_spec.rb

実行結果

Country
  associations
    is expected to have many quiz_attempts dependent => destroy
    is expected to have many user_flags dependent => destroy
    is expected to have many users through user_flags
  validations
    is expected to validate that :name cannot be empty/falsy
    is expected to validate that :name is case-sensitively unique
    is expected to validate that :hint_1 cannot be empty/falsy
    is expected to validate that :hint_2 cannot be empty/falsy
    is expected to validate that :hint_3 cannot be empty/falsy
    is expected to validate that :hint_4 cannot be empty/falsy
    is expected to validate that :flag_url cannot be empty/falsy
  factory
    有効なファクトリを持つこと

Finished in 0.80733 seconds
11 examples, 0 failures

テストが通っていることが確認できました!

まとめ

Railsでモデルのテストを書く流れ:

  1. マイグレーション作成・実行 → テーブル作成
  2. モデルファイル作成 → バリデーションとアソシエーション定義
  3. ファクトリー定義 → テストデータの雛形作成
  4. テストファイル作成 → RSpecでテストケース記述
  5. テスト実行 → 動作確認

この流れを押さえておけば、他のモデルでも同様に実装できます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?