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を使用したモデルの単体テスト

Last updated at Posted at 2025-05-06

記事概要

Ruby on Railsのモデル単体テストについて、まとめる

前提

  • Ruby on Railsでアプリケーションを作成している
  • アプリにRSpecをインストールしている
  • RSpecの設定が完了している

RSpecとは

モデルテストコードを書く方針

インスタンスを生成し、それがモデルに規定したどおりの挙動になるか、を確かめる
例)バリデーションが正しく働くか

手順(テストファイル作成)

  1. モデルのテストファイルを生成するため、下記コマンドを実行する
    # アプリのディレクトリに移動
    % cd ~/[アプリ名]
    
    % rails g rspec:model [モデル名]
    
  2. spec/models/モデル名_spec.rbが作成されたことを確認する
  3. モデル名_spec.rbrequire 'rails_helper'が記述されていることを確認する
    require 'rails_helper'
    
    RSpec.describe モデル名, type: :model do
      pending "add some examples to (or delete) #{__FILE__}"
    end
    
  4. 上記からpending "add some examples to (or delete) #{__FILE__}"を削除する
    require 'rails_helper'
    
    RSpec.describe モデル名, type: :model do
      
    end
    

手順(テスト用ダミー画像の用意)

  1. publicディレクトリにimagesフォルダを手動作成する
  2. public/imagesフォルダに、ダミー画像を格納する

手順(テストケースの記述)

  1. [モデル名]_spec.rbにテストケースを記述する
    1. 機能別・条件別・テスト詳細別にグループ分けを行う
    2. 保存するデータ(インスタンス)を作成する
    3. テストコードを記述する
      ※各テストコードが想定通りに実行できるかを確認するため、rails cコマンドでコンソールを起動して確認を行う

手順(テストファイルの実行)

  1. テストファイルを実行するため、下記コマンドを実行する
    # アプリのディレクトリに移動
    % cd ~/[アプリ名]
    
    % bundle exec rspec spec/models/モデル名_spec.rb 
    
  2. ターミナル.appで正常完了していることを確認する
    結果が緑色で表示されれば実行成功

まとめ

画像添付した際にエラー発生

active_storageを用いたモデルの単体テストをする際に、エラーMySQL client is not connectedが発生した場合、下記を追記する

config/environments/test.rb
Rails.application.configure do
  # MySQLのエラーが発生する場合、追記
  config.active_job.queue_adapter = :inline
  
  # 省略
end

devise(Gem)のデフォルトバリデーション

  • emailが空では登録できない
  • passwordが空では登録できない
  • emailは@を含まないと登録できない
  • 重複したemailが存在する場合は登録できない
  • passwordとpassword_confirmationが不一致では登録できない
  • passwordが5文字以下では登録できない
  • passwordが129文字以上では登録できない

参考コード

他モデルと紐付けなし

require 'rails_helper'

RSpec.describe User, type: :model do
  before do
    @user = FactoryBot.build(:user)
  end

  describe 'ユーザー新規登録' do
    context 'ユーザー登録できるとき' do
      it 'nicknameとemail、passwordとpassword_confirmationが存在すれば登録できる' do
        expect(@user).to be_valid
      end
    end
    context 'ユーザー登録できないとき' do
      it 'nicknameが空では登録できない' do
        @user.nickname = ''
        @user.valid?
        expect(@user.errors.full_messages).to include("Nickname can't be blank")
      end
      it 'passwordとpassword_confirmationが不一致では登録できない' do
        @user.password_confirmation = "#{@user.password_confirmation}123"
        @user.valid?
        expect(@user.errors.full_messages).to include("Password confirmation doesn't match Password")
      end
      it 'nicknameが7文字以上では登録できない' do
        @user.nickname = 'aaaaaaa'
        @user.valid?
        expect(@user.errors.full_messages).to include('Nickname is too long (maximum is 6 characters)')
      end
      it '重複したemailが存在する場合は登録できない' do
        @user.save
        another_user = FactoryBot.build(:user)
        another_user.email = @user.email
        another_user.valid?
        expect(another_user.errors.full_messages).to include('Email has already been taken')
      end
      it 'emailは@を含まないと登録できない' do
        @user.email = 'testmail'
        @user.valid?
        expect(@user.errors.full_messages).to include('Email is invalid')
      end
      it 'passwordが5文字以下では登録できない' do
        @user.password = '00000'
        @user.password_confirmation = @user.password
        @user.valid?
        expect(@user.errors.full_messages).to include('Password is too short (minimum is 6 characters)')
      end
      it 'passwordが129文字以上では登録できない' do
        @user.password = Faker::Internet.password(min_length: 129, max_length: 150)
        @user.password_confirmation = @user.password
        @user.valid?
        expect(@user.errors.full_messages).to include("Password is too long (maximum is 128 characters)")
      end
    end
  end
end

他モデルと紐付けあり+画像の紐付けあり

require 'rails_helper'

RSpec.describe Message, type: :model do
  before do
    @message = FactoryBot.build(:message)
  end

  describe 'メッセージ投稿' do
    context 'メッセージが投稿できる場合' do
      it 'contentとimageが存在していれば保存できる' do
        expect(@message).to be_valid
      end
      it 'imageが空でも保存できる' do
        @message.image = nil
        expect(@message).to be_valid
      end
    end
    context 'メッセージが投稿できない場合' do
      it 'contentとimageが空では保存できない' do
        @message.content = ''
        @message.image = nil
        @message.valid?
        expect(@message.errors.full_messages).to include("Content can't be blank")
      end
      it 'userが紐付いていないと保存できない' do
        @message.user = nil
        @message.valid?
        expect(@message.errors.full_messages).to include('User must exist')
      end
    end
  end
end

Ruby on Railsまとめ

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?