LoginSignup
1
2

More than 3 years have passed since last update.

deviseを使用したuserモデルバリデーションチェックのRSpec初コーディング(前編)

Last updated at Posted at 2021-04-12

時間をかけ調べました。
間違っている箇所があればご指摘お願いします。

自分がかけたバリデーションチェックのRSpecをコーディングを公開します。

views/devise/registrations/new.thml.erb

20210413-000555.png

20210413-000634.png

すべて必須なので全項目に---presence: true
のバリデーションがかかっています。

このテストコードを難しいと感じる点

Q1.生年月日欄 どのようにテストコードを書けば良いのか?

数字3つ用意して、「年」「月」「日」を間に挟むのか??? +とかでつなぐのか?

valid?というコードの目的を知るとわかる

Q2.最低字数6文字で英数混合のパスワードを作る

ググっても6文字で英数混合パスワードというものは出てこない。うーーっ

Fakerのパスワードで実現するのはムズカしいと知ることから始まる

Q3.エラーメッセージはどんなメッセージを書くのか?

これから作るアプリ完成時の表示を想像しないといけない。これまた難問。ググるか?

何に対してテストするかを考える。

テストの仕様

バリデーションチェック「正常系」
①全ての項目がきちんと条件通り揃ってusersテーブルに「保存」される
→全て必須なので1通りのみ

バリデーションチェック「異常系」
②1つの項目が欠けた場合を想定して、全ての項目で欠けたパターンのusersテーブルに「保存」されないチェック
→全ての項目なのでニックネーム・メールアドレス・パスワード・パスワード(確認)・お名前(姓)・お名前(名)・お名前(カナ・姓)・お名前(カナ・名)・生年月日の9通り

実装に向けての準備

Gemfile
group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails', '~> 4.0.0'
  gem 'factory_bot_rails'
  gem 'faker'
  gem 'gimei'
end

RSpec:Ruby専用テスティングフレームワーク
faker:テスト用のダミーデータをランダムに生成するGem
gimei:日本語対応のテスト用のダミーデータをランダムに生成するGem

以上をインストールしました。

terminal
bundle install

次に

terminal
rails g rspec:install

さらに
fakerの作成ダミーデータの仕様決定のためのファイルを用意します。
specフォルダの下にfactoriesというフォルダと「テーブル名(複数形名)」.rbのフォルダを作って用意します。
20210413-004120.png

ダミーデータの仕様を決める設計図

以下になります。

spec/factories/users.rb
FactoryBot.define do
     #1.ニックネーム
    nickname {Faker::Name.last_name}
     #2.メールアドレス
    email {Faker::Internet.free_email}
     #3.パスワード
    password {Faker::Lorem.characters(number: 10, min_alpha: 4, min_numeric: 1) }
     #4.確認用パスワード
    password_confirmation {password}
     #5.漢字(姓)
    first_name { Gimei.first.kanji }
     #6.漢字(名)
    last_name { Gimei.last.kanji }
     #7.漢字(姓・カナ)#pronoはpronounceでカナとしています。
    first_name_prono { Gimei.first.katakana }
     #8.漢字(名・カナ)#pronoはpronounceでカナとしています。
    last_name_prono { Gimei.last.katakana }
     #9.生年月日
    birthday { Faker::Date.backward }
  end
end

Gimei.first.kanjiはGimeiGemのおかげで漢字が入ります。
Gimei.last.kanjiも同様に漢字が入ります。
Gimei.first.katakanaはGimeiGemのおかげでカタカナが入ります。
Gimei.last.katakanaはGimeiGemのおかげでカタカナが入ります。

password {Faker::Lorem.characters(number: 10, min_alpha: 4, min_numeric: 1) }
については6文字で英数混合の設定にとても苦労したので、別で詳しく解説しています。よければリンク先でご確認いただければと思います。

Fakerを使って英数混合のパスワードを作る(Q2の解答にもなっております)
↓↓↓

https://qiita.com/takuo_maeda/items/70a3fb2cc190099f3a5e

はじめて書いたテストコード

user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  describe '#create' do
    before do
      #インスタンス変数で渡す:理由 describe,itの変数のスコープが違うので
      #:userはハッシュのシンボルになっていてspec/factories/users.rbで作った設計図通りの
       ランダムなダミーデータを作ってくれます。
      @user = FactoryBot.build(:user)
    end
    #正常系
    it 'nickame,email,password,password_confirmation,first_name,last_name,first_name_prono,last_name_prono,birthdayの値が存在すれば登録できること' do
      expect(@user).to be_valid
    end
   
   #異常系1
    it 'nicknameが空では登録できないこと' do
      @user.nickname = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("Nickname can't be blank")
    end
   #異常系2
    it 'emailが空では登録できないこと' do
      @user.email = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("Email can't be blank")
    end
   #異常系3
    it 'paswordが空では登録できないこと' do
      @user.password = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("Password can't be blank")
    end
   #異常系4
    it 'pasword_confirmationが空では登録できないこと' do
      @user.password_confirmation = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("Password confirmation can't be blank")
    end
   #異常系5
    it 'first_nameが空では登録できないこと' do
      @user.first_name = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("First name can't be blank")
    end
   #異常系6
    it 'last_nameが空では登録できないこと' do
      @user.last_name = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("Last name can't be blank")
    end
   #異常系7
    it 'first_name_pronoが空では登録できないこと' do
      @user.first_name_prono = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("First name prono can't be blank")
    end
    #異常系8
    it 'last_name_pronoが空では登録できないこと' do
      @user.last_name_prono = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("Last name prono can't be blank")
    end
   #異常系9
    it 'birthdayが空では登録できないこと' do
      @user.birthday = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("Birthday can't be blank")
    end
  end
end

参考
・valid?メソッドは以下の2つの役割
*Q3の「エラーメッセージはどんなメッセージを書くのか?」の解答にもなっています。

①true/falseを返す

true false
作成したデータが正しく保存される場合 保存されない場合はfalse

②保存されない場合は「なぜ保存されないのか」のエラーメッセージを生成する

Q3の解答

・バリデーション presence: trueは空欄では保存できない
・それに対応するエラーメッセージは「〜can't be blank」(=空欄で保存はできない)

参考:エラーメッセージ集
②の理由からincludeの後に表示されるメッセージを書くことになっています。テストを作った後にbinding.pryしてコンソールでどんなメッセージが表示されるのかを取得しておきました。ご参考まで。

取得コマンド
@user.errors.full_messages

エラーメッセージはモデルのerrorsに格納されています。
*userモデルなので @userになっています。

[1] pry(#<RSpec::ExampleGroups::User::Nested>)> user.errors.full_messages
=> ["Email can't be blank",
 "Email can't be blank",
 "Password can't be blank",
 "Nickname can't be blank",
 "Encrypted password can't be blank",
 "First name can't be blank",
 "Last name can't be blank",
 "First name prono can't be blank",
 "Last name prono can't be blank"]

基本:userモデルバリデーションで「presence: ture」とした場合のエラーメッセージは
「〜can't be blank」が共通部分となります。
’保存先カラム名を元に、〜部分の主語を変え、先頭を大文字にし、スネークケースで命名されていれば_(アンダーバー)をはずして主語を書いてください。’

Q2の解答

姓年月日がどんなview画面で構成されているかはいっさい関係いなく
データベースに保存されるかされないかをテストしているので保存されているデータの形式を確認してテストコードを書けば良い。

データベースには以下のようにデータが保存されているので

20210413-220027.png

rails
fakerFaker::Date.backward

こうすると
テストが成功すると「2019-01-03」のようなダミーデータを作ってくれます。

terminal
nickame,email,password,password_comfirmation,first_name,last_name,first_name_prono, 
    last_name_prono,birthdayの値が存在すれば登録できること
    nicknameが空では登録できないこと
    emailが空では登録できないこと
    paswordが空では登録できないこと
    pasword_confirmationが空では登録できないこと
    first_nameが空では登録できないこと
    last_nameが空では登録できないこと
    first_name_pronoが空では登録できないこと
    last_name_pronoが空では登録できないこと
    birthdayが空では登録できないこと

ひとまず段落です。

参考
単体テストコードRspecでの.validか.valid?か(初期の私の記事です。よかったら)

https://qiita.com/takuo_maeda/items/8755d38ca24172225250

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