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

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

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

####views/devise/registrations/new.thml.erb
![20210413-000555.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/8b70a463-2a70-055f-591b-c4b1cdde071c.png)


![20210413-000634.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/b616b155-d5c6-3937-c570-8d24272082f1.png)


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

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

####Q1.生年月日欄　どのようにテストコードを書けば良いのか？
数字３つ用意して、「年」「月」「日」を間に挟むのか？？？ ＋とかでつなぐのか？
######`valid?というコードの目的を知るとわかる`

####Q2.最低字数６文字で英数混合のパスワードを作る
ググっても６文字で英数混合パスワードというものは出てこない。うーーっ
######`Fakerのパスワードで実現するのはムズカしいと知ることから始まる`

####Q3.エラーメッセージはどんなメッセージを書くのか？
これから作るアプリ完成時の表示を想像しないといけない。これまた難問。ググるか？
######`何に対してテストするかを考える。`


テストの仕様
-

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

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

実装に向けての準備
-

```rb: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:terminal
bundle install
```

次に

```terminal:terminal
rails g rspec:install
```

さらに
fakerの作成ダミーデータの仕様決定のためのファイルを用意します。
specフォルダの下にfactoriesというフォルダと「テーブル名（複数形名）」.rbのフォルダを作って用意します。
![20210413-004120.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/f0eed035-7dbd-7f8e-7a87-35a1346c8afe.png)


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

以下になります。

```rb: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) }
については６文字で英数混合の設定にとても苦労したので、別で詳しく解説しています。よければリンク先でご確認いただければと思います。

Fakerを使って英数混合のパスワードを作る（Q２の解答にもなっております）
↓↓↓

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


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

```rb: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
　　　
　　 #異常系１
    it 'nicknameが空では登録できないこと' do
      @user.nickname = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("Nickname can't be blank")
    end
　　 #異常系２
    it 'emailが空では登録できないこと' do
      @user.email = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("Email can't be blank")
    end
　　 #異常系３
    it 'paswordが空では登録できないこと' do
      @user.password = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("Password can't be blank")
    end
　　 #異常系４
    it 'pasword_confirmationが空では登録できないこと' do
      @user.password_confirmation = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("Password confirmation can't be blank")
    end
　　 #異常系５
    it 'first_nameが空では登録できないこと' do
      @user.first_name = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("First name can't be blank")
    end
　　 #異常系６
    it 'last_nameが空では登録できないこと' do
      @user.last_name = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("Last name can't be blank")
    end
　　 #異常系７
    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
 　　 #異常系８
    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
　　 #異常系９
    it 'birthdayが空では登録できないこと' do
      @user.birthday = ''
      @user.valid?
      expect(@user.errors.full_messages).to include("Birthday can't be blank")
    end
  end
end
```


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

①true/falseを返す

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

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

Q3の解答
-


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

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

|取得コマンド|
|:------------:|
|@user.errors.full_messages|


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



```ruby
[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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/e4447bb3-349b-213d-3487-05de024d200f.png)

```rb:rails
fakerにFaker::Date.backward
```

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


```terminal: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