4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

私立探求学園 Advent Calendar 2020

Day 21

自宅待機中に ModelSpec について学習した

Last updated at Posted at 2020-12-22

新型コロナウィルスの影響で会社から自宅待機を命じられました。

いい機会と思い、ModelSpec について学習したことをまとめました。

この記事で分かること

  • バリデーションテストの考え方
  • ModelSpec の基本的な記述の仕方

この記事でやらないこと

  • gem の導入手順
  • ModelSpec の説明
  • 必要なファイルの準備
  • let を使用した変数定義
  • FactoryBot や Faker を使用した記述

目次

  1. 開発環境
  2. テストする Model のバリデーション
  3. RSpec の雛形を確認
  4. context ブロックにテストする項目を書き出す
  5. it ブロックに期待する結果を書く
  6. it ブロックが叶うように、 context ブロックで御膳立てをする

1. 開発環境

Rails 6.0.3.4

ruby 2.7.1

rspec-rails 4.0.1

2. テストする Model のバリデーション

app/models/user.rb
validates :name, :account_name, :email, : presence: true

今回はこのようなバリデーションをテストしていきます。
「name, account_name, email カラムは必須の項目です」といった内容ですね。

3. RSpec の雛形を確認

EX-IT.png
こちらが RSpec の基本的な形になります。
target にはテストしたい内容が入り、〇〇〇にはその結果が入ります。

イメージ的には以下のような感じですね。

expect( 1 + 1 ).to eq 2

また、.to の直後の eq はマッチャと呼ばれるもので様々な種類があるのですが、今回は説明を割愛します。詳しくは こちら の記事をご覧ください。

今回は以下の2種類のマッチャを使用します。

be_valid ... 「バリデーション が適切です」を意味するマッチャ。

be_invalid ... 「バリデーション が不適切です」を意味するマッチャ。

それでは実際に ModelSpec を書いていきましょう。

4. context ブロックにテストの条件を記述する。

「テストの条件」と聞くと難しく聞こえますが、「正常な場合と異常な場合をそれぞれテストする」と考えても OK です。

これらはそれぞれ「正常系テスト」「異常系テスト」と呼ばれます。

今回の場合だと、正常系テストは

name カラム、account_name カラム、email カラムが全て指定されている場合

になります。

反対に、異常系テストは

name カラムが指定されていない場合

account_name カラムが指定されていない場合

email カラムが指定されていない場合

になりますね。実際にコードを書いてみましょう。

require "rails_helper"

RSpec.describe User, type: :model do
  describe "#validation" do
    # 正常系
    context "name, account_name, email が全て指定されている場合" do
        
      it "" do
          
      end
    end
      
    # 異常系
    context "name が指定されていない場合" do
      it "" do
          
      end
    end
      
      #異常系
    context "account_name が指定されていない場合" do
      it "" do
          
      end
    end
      
    # 異常系
    context "email が指定されていない場合" do
      it "" do
          
      end
    end
  end
end

5. it ブロックに期待する結果を書く

it ブロックは期待する結果を書く場所でしたね。正常系テストは上手く通ればユーザーが作られる想定なので、そのまま書きましょう。

反対に異常系テストが上手く通るということは、エラー起こるということなので、こちらも同じように書きます。

require "rails_helper"

RSpec.describe User, type: :model do
  describe "#validation" do
    # 正常系
    context "name, email, password, account_name が全て指定されている場合" do
        
      it "ユーザーが作られる" do
          
      end
    end
      
    # 異常系
    context "name が指定されていない場合" do
      it "エラーする" do
          
      end
    end
      
      #異常系
    context "account_name が指定されていない場合" do
      it "エラーする" do
          
      end
    end
      
    # 異常系
    context "email が指定されていない場合" do
      it "エラーする" do
          
      end
    end
  end
end

さらに、 it ブロックの中身も書いていきましょう。正常系の場合は、以下になります。

expect( user ).to be_valid

変数 user に User インスタンスを格納することを想定した記述になっています。この1行で、

user のバリデーションは適切である

といった意味になります。

異常系テストの場合は以下のようになりますね。

expect( user ).to be_invalid

それぞれ it ブロック内に記載していきましょう。

require "rails_helper"

RSpec.describe User, type: :model do
  describe "#validation" do
    # 正常系
    context "name, email, password, account_name が全て指定されている場合" do
        
      it "ユーザーが作られる" do
    	expect( user ).to be_valid
      end
    end
      
    # 異常系
    context "name が指定されていない場合" do
      it "エラーする" do
         expect( user ).to be_invalid
      end
    end
      
      #異常系
    context "account_name が指定されていない場合" do
      it "エラーする" do
         expect( user ).to be_invalid
      end
    end
      
    # 異常系
    context "email が指定されていない場合" do
      it "エラーする" do
         expect( user ).to be_invalid
      end
    end
  end
end

6. it ブロックが叶うように、 context ブロックで御膳立てをする

ここまできたら、あとは it ブロック内が実現されるように context ブロック内を埋めていきましょう。まずは正常系テストから。正常系テストの条件は、

name カラム、account_name カラム、email カラムが全て指定されている場合

だったので、普通にインスタンスを作成すれば良さそうですね。

user = User.new(name: "user", account_name: "user_account_name", email: "user@example.com")

次に異常系テストです。一つだけ具体例をみてみましょう。

name カラムが指定されていない場合

これは name カラムを nil にしてあげれば良さそうです。

 user = User.new(name: nil, account_name: "user_account_name", email: "user@example.com")

同じ要領で他の異常系テストも記述していきましょう。完成したものが以下になります。

require "rails_helper"

RSpec.describe User, type: :model do
  describe "#validation" do
    # 正常系
    context "name, email, password, account_name が全て指定されている場合" do
      user = User.new(name: "user", account_name: "user_account_name", email: "user@example.com")
      it "ユーザーが作られる" do
    	expect( user ).to be_valid
      end
    end
      
    # 異常系
    context "name が指定されていない場合" do
      user = User.new(name: nil, account_name: "user_account_name", email: "user@example.com")
      it "エラーする" do
         expect( user ).to be_invalid
      end
    end
      
      #異常系
    context "account_name が指定されていない場合" do
      user = User.new(name: "user", account_name: nil, email: "user@example.com")
      it "エラーする" do
         expect( user ).to be_invalid
      end
    end
      
    # 異常系
    context "email が指定されていない場合" do
         user = User.new(name: "user", account_name: "user_account_name", email: nil)
      it "エラーする" do
         expect( user ).to be_invalid
      end
    end
  end
end

最後に

はい、ここまでお疲れ様でした。

今回の内容はあくまでも初歩的な内容だったかと思います。

今後は FactoryBot や Faker を組み合わせた内容をやっていく予定です。

最後まで読んでいただき、ありがとうございました!

4
2
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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?