個人的には記述どうのこうのよりも事前準備にすごく手間取りました。
簡単に今回のUsersテーブルを示すと
Column | Type | Option |
---|---|---|
nickname | string | null,false |
string | null,false, unique: true | |
encrypted_password | string | null,false |
last_name | string | null,false |
first_name | string | null,false |
last_name_kana | string | null,false |
first_name_kana | string | null,false |
birth_date | date | null,false |
名前は全角で、カナまであります。
この辺のバリデーションが結構めんどくさかった。
そしてテストコードを記述するためにFactorybot、Faker、Gimeiを使用しました。
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
で、いつも通り、spec配下にfactoriesとuser.rbを作成します。
spec/factories/users.rb
FactoryBot.define do
factory :user do
transient do
person { Gimei.name }
end
nickname { Faker::Name.initials(number: 2) }
email { Faker::Internet.free_email }
password { "g9" + Faker::Internet.password(min_length: 6) }
password_confirmation { password }
first_name { person.first.kanji }
last_name { person.last.kanji }
first_name_kana { person.first.katakana }
last_name_kana { person.last.katakana }
birth_date { Faker::Date.backward }
end
end
これで、テストで作成されるユーザーが出来ました。
パスワードのところに謎の"g9"が現れてますが、これは何でも良いです。
ただ今回の実装条件に、パスワードは英数字を含める、という条件があったので、文頭につけておきました。
ぶっちゃけここまでがめんどくさかっただけで、後のテストコードはバリデーションがきちんと働いているかのテストなので、記述自体は楽ちん。
ただバリデーションが多いので、記述量が多いのが面倒くさい・・・
テストコードはこんな感じです。
spec/models/user_spec.rb
require 'rails_helper'
RSpec.describe User, type: :model do
before do
@user = FactoryBot.build(:user)
end
describe 'ユーザー新規登録' do
context '新規登録できるとき' do
it '正常に登録できる' do
expect(@user).to be_valid
end
it 'passwordとpassword_confirmationが6文字以上であれば登録できる' do
@user.password = 'test1234'
@user.password_confirmation = 'test1234'
expect(@user).to be_valid
end
it 'first_nameとlast_nameが全角であれば登録できる' do
@user.first_name = '桐生'
@user.last_name = 'ココ'
expect(@user).to be_valid
end
it 'first_name_kanaとlast_name_kanaが全角であれば登録できる' do
@user.first_name_kana = 'イオフィ'
@user.last_name_kana = 'イナニス'
expect(@user).to be_valid
end
end
context '新規登録出来ない時' do
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 'passwordが空では登録できない' do
@user.password = ''
@user.valid?
expect(@user.errors.full_messages).to include("Password can't be blank")
end
it 'passwordが存在してもpassword_confirmationが空では登録できない' do
@user.password_confirmation = ''
@user.valid?
expect(@user.errors.full_messages).to include("Password confirmation doesn't match Password")
end
it 'passwordが数字だけだと登録できない' do
@user.password ='11111111'
@user.password_confirmation = '11111111'
@user.valid?
expect(@user.errors.full_messages).to include("Password パスワードには半角英字と半角数字の両方を含めて設定してください")
end
it 'passwordが英字だけだと登録できない' do
@user.password = 'aaaaaaaa'
@user.password_confirmation = 'aaaaaaaa'
@user.valid?
expect(@user.errors.full_messages).to include("Password パスワードには半角英字と半角数字の両方を含めて設定してください")
end
it 'passwordが全角だと登録できない' do
@user.password = 'ああああああ'
@user.password_confirmation = 'ああああああ'
@user.valid?
expect(@user.errors.full_messages).to include("Password パスワードには半角英字と半角数字の両方を含めて設定してください")
end
it 'passwordとconfirmが一致していないと登録できない' do
@user.password = 'test123'
@user.password_confirmation ='test1234'
@user.valid?
expect(@user.errors.full_messages).to include("Password confirmation doesn't match Password")
end
it 'passwordが英数字混合でも6文字未満なら登録できない' do
@user.password ='test1'
@user.password_confirmation = 'test1'
@user.valid?
expect(@user.errors.full_messages).to include("Password is too short (minimum is 6 characters)")
end
it '重複したemailが存在する場合登録できない' do
@user.save
another_user = FactoryBot.build(:user)
another_user.email = @user.email
another_user.valid?
expect(another_user.errors.full_messages).to include('Email has already been taken')
end
it 'emailには@が含まれていないと登録できない' do
@user.email = 'aaaaaaa'
@user.valid?
expect(@user.errors.full_messages).to include('Email is invalid')
end
it 'first_nameが空では登録できない' do
@user.first_name = ''
@user.valid?
expect(@user.errors.full_messages).to include("First name can't be blank", "First name 全角ひらがな、全角カタカナ、漢字で入力して下さい")
end
it 'first_nameが半角では登録できない' do
@user.first_name = 'aaaa'
@user.valid?
expect(@user.errors.full_messages).to include("First name 全角ひらがな、全角カタカナ、漢字で入力して下さい")
end
it 'last_nameが空では登録できない' do
@user.last_name = ''
@user.valid?
expect(@user.errors.full_messages).to include("Last name can't be blank", "Last name 全角ひらがな、全角カタカナ、漢字で入力して下さい")
end
it 'last_nameが半角では登録できない' do
@user.last_name = 'aaaa'
@user.valid?
expect(@user.errors.full_messages).to include("Last name 全角ひらがな、全角カタカナ、漢字で入力して下さい")
end
it 'first_name_kanaが空では登録できない' do
@user.first_name_kana = ''
@user.valid?
expect(@user.errors.full_messages).to include("First name kana can't be blank", "First name kana 全角カタカナで入力して下さい")
end
it 'first_name_kanaが半角では登録できない' do
@user.first_name_kana = 'aaaa'
@user.valid?
expect(@user.errors.full_messages).to include("First name kana 全角カタカナで入力して下さい")
end
it 'last_name_kanaが空では登録できない' do
@user.first_name_kana = ''
@user.valid?
expect(@user.errors.full_messages).to include("First name kana can't be blank", "First name kana 全角カタカナで入力して下さい")
end
it 'last_name_kanaが半角では登録できない' do
@user.first_name_kana = 'aaaaa'
@user.valid?
expect(@user.errors.full_messages).to include("First name kana 全角カタカナで入力して下さい")
end
it 'birth_dateが空では登録できない' do
@user.birth_date = ''
@user.valid?
expect(@user.errors.full_messages).to include("Birth date can't be blank")
end
end
end
end
なんでもかんでもバリデーションはつけるものではないですね・・・
必要なものだけにバリデーションはつけましょう。
はっきり言って、面倒臭いです・・・