RspecでModelをテスト

前回導入したRspecでテストを書いてみる。

今回はUserのモデルを実装してテストする。

さくっと...

rails g model name:string login_id:string password:string

次に規約を決める...テストなので凝らずにシンプルで。
name => ユニーク、必須入力
login_id => ユニーク、必須入力、6~20文字、 半角英数字のみ
password => 必須入力、6~20文字、半角英数字のみ

これが決まったら早速テストクラスを作成する。

rails g rspec:model user

これでテストが書けるようになったので先程決めた仕様に基づいて実装する。

RSpec.describe User do

  let(:error_strs){ %w[errorStr1あ errorStr1&%]  }
  let(:user){ build_stubbed :user  }

  describe '#name' do
    it '必須入力'do
      is_expected.to validate_presence_of(:name)
    end
  end

  describe '#password' do
    it '必須入力' do
      is_expected.to validate_presence_of(:password)
    end
    it '長さチェック' do
      is_expected.to ensure_length_of(:password).is_at_least(6).is_at_most(20)
    end
    it '半角英数字以外はバリデーションエラー' do
      error_strs.each do |error_password|
        user.password = error_password
        expect(user).not_to be_valid
      end
    end
  end

  describe '#login_id' do
    it '必須入力' do
      is_expected.to validate_presence_of(:login_id)
    end
    it '長さチェック' do
      is_expected.to ensure_length_of(:login_id).is_at_least(6).is_at_most(20)
    end
    it 'ユニークテスト' do
      is_expected.to validate_uniqueness_of(:login_id)
    end
    it '半角英数字以外はバリデーションエラー' do
      error_strs.each do |error_id|
        user.login_id = error_id
        expect(user).not_to be_valid
      end
    end
  end

end

で実装したらテストを走らせる。

bundle exec rspec spec/models/user_spec.rb

勿論失敗。
今度は成功するようにモデルにバリデーションを実装する。

class User < ActiveRecord::Base
  
  validates :name, :password, :login_id,  presence: true
  validates :login_id, :password, length: { in: 6..20 }
  validates :login_id, uniqueness: true
  validates :login_id, :password, format: { with: /\A(?!\d*\z)[a-z0-9]+\z/i }
end

もう一度テストを実行すると今度は成功になる。