【Rails】モデルスペックの基礎【RSpec】


 モデルスペックにおいての正常系/異常系

 そもそも正常系,異常系とは

 正常系

簡単に言うと、想定されたインプット(初期化等)があった時に、想定されたアウトプットや状態を得ることができること。

 異常系

想定されていないインプットがあった時に、エラーを出力されるなどの想定されたアウトプットが得ることができるということ

 【例】ユーザー登録の場合

下記のデータを要求しているモデルがあったとする。

  • name
  • email address

上記の二つを満たしていれば、登録できる→正常系
上記の二つのうち一つでも欠けていると登録できない→異常系

 モデルスペックでの正常系/異常系を考える

  • 正常な属性を持つモデルであれば有効
  • バリデーション(異常)に引っかかる属性であれば無効

こんな感じで区別できますよね。

 よくわからないけど、書いてみようぜ。

前提

userモデルは下記の項目を必要とする。

  • name
  • password
  • email

email address重複不可

 アウトラインから書いてみよう

require 'rails_helper'

RSpec.describe User, type: :model do
  # name,email,passwordがあれば有効
  it "is valid with a name,email, and password" 
  # nameが欠けていた場合は無効
  it "is invalid without a name" 
  # emailが欠けていた場合は無効
  it "is invalid without an email address"
  # emailが重複している場合は無効
  it "is invalid with a duplicate email address"
end

こんな感じでそのテストの概要を書いていきました。ここから中身をどんどん書いていきます!

バリデーションだけを対象とした簡単なモデルスペックです。クラスメソッドやインスタンスメソッドのスペックは今回は割愛。)

 実際にスペックを書いていく

require 'rails_helper'

RSpec.describe User, type: :model do

  it "is valid with a name,email, and password" do
    user = User.new(
      name: "おにかん"
      password: "testpassword"
      email: "[email protected]"
    )
    expect(user).to be_valid 
  end

  it "is invalid without a name" do
    user.new(name: nil)
    user.valid?

    expect(user.errors[:name]).to include("can't be blank")
  end

  it "is invalid without an email address" do
    user.new(email: nil)
    user.valid?

    expect(user.errors[:email]).to include("can't be blank")
  end

  it "is invalid with a duplicate email address" do
    User.create(
      name: "おにかん"
      password: "testpassword"
      email: "[email protected]"
    )

    user = User.new(
      name: "おに"
      password: "test2password"
      email: "[email protected]"
    )

    expect(user.errors[:email]).to include("has already been taken")
  end
end

基本の形だけ解説していきます。

expect(user).to be_valid

ここではuserオブジェクトが「有効」かどうか判断されています。expectの引数の中に判定したいオブジェクト名を入れ、.to.not_toメソッドに繋げます。be_validは「有効である」という状態を表します。

be_validは「マッチャ」と呼ばれ、この他にも色々あるので、気になる方はググってみてください。

以上です。基本の雰囲気だけ詰め込みました。ご指摘等あればコメントしていただけるとありがたいです🙇‍♂️