実現したいこと
Ruby on railsのテストコードでexpectedに正しいデータが入って単体テストが通るようにしたい.
前提
ユーザー管理機能のテストコードを入力しています。
発生している問題・エラーメッセージ
重複したメールアドレスのことを言っているのにexpectedにはPasswordのことが入っています。
User ユーザー新規登録 新規登録できない場合 重複したメールアドレスは登録できない Failure/Error: expect(another_user.errors.full_messages).to include('Email has already been taken') expected ["Password パスワードは英数字混合の6文字以上です。"] to include "Email has already been taken" # ./spec/models/user_spec.rb:60:in `block (4 levels) in <top (required)>'
該当のソースコード
Ruby
1require 'faker/japanese' 2 3FactoryBot.define do 4 factory :user do 5 nickname { Faker::Name.unique.name } #ニックネームのようなダミーデータの生成 6 email { Faker::Internet.unique.email } # メールアドレスのようなダミーデータの生成 7 password { Faker::Alphanumeric.alphanumeric(number: 6, min_alpha: 1, min_numeric: 1) } 8 password_confirmation { password } 9 family_name { Faker::Japanese::Name.last_name } 10 first_name { Faker::Japanese::Name.first_name } 11 family_name_kana { "ササキ" } 12 first_name_kana { "コジロー" } 13 birthday { Faker::Date.birthday(min_age: 18, max_age: 65) } 14 end 15end
テストコード全体
require 'rails_helper' RSpec.describe User, type: :model do before do @user = FactoryBot.build(:user) end describe 'ユーザー新規登録' do context '新規登録できる場合' do it "nicknameとemail、passwordとpassword_confirmation、family_nameとfirst_name、family_name_kanaとfirst_name_kana、birthdayが存在すれば登録できる" do 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 "family_nameが空では登録できない" do @user.family_name = '' @user.valid? expect(@user.errors.full_messages).to include("Family name 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 "family_name_kanaが空では登録できない" do @user.family_name_kana = '' @user.valid? expect(@user.errors.full_messages).to include("Family name kana can't be blank") 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") end it "birthdayが空では登録できない" do @user.birthday = '' @user.valid? expect(@user.errors.full_messages).to include("Birthday can't be blank") end it '重複したメールアドレスは登録できない' 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 'メールアドレスに@を含まない場合は登録できない' do @user.email = 'testmail' @user.valid? expect(@user.errors.full_messages).to include('Email is invalid') end it 'パスワードが6文字未満では登録できない' do @user.password = '00000' @user.password_confirmation = '00000' @user.valid? expect(@user.errors.full_messages).to include('Password is too short (minimum is 6 characters)') end it '英字のみのパスワードでは登録できない' do @user.password = 'aaaaaa' @user.password_confirmation = 'aaaaaa' @user.valid? expect(@user.errors.full_messages).to include('Password パスワードは英数字混合の6文字以上です。') end it '数字のみのパスワードでは登録できない' do @user.password = '000000' @user.password_confirmation = '000000' @user.valid? expect(@user.errors.full_messages).to include('Password パスワードは英数字混合の6文字以上です。') end it '全角文字を含むパスワードでは登録できない' do @user.password = 'aaa 111' @user.password_confirmation = 'aaa 111' @user.valid? expect(@user.errors.full_messages).to include('Password パスワードは英数字混合の6文字以上です。') end it 'パスワードとパスワード(確認用)が不一致だと登録できない' do @user.password = '123456' @user.password_confirmation = '1234567' @user.valid? expect(@user.errors.full_messages).to include("Password confirmation doesn't match Password") end it '姓(全角)に半角文字が含まれていると登録できない' do @user.family_name = 'ヤマダ' @user.valid? expect(@user.errors.full_messages).to include('Family name 氏名は全角でお願いします。') end it '名(全角)に半角文字が含まれていると登録できない' do @user.first_name = 'タロウ' @user.valid? expect(@user.errors.full_messages).to include('First name 氏名は全角でお願いします。') end it '姓(カナ)にカタカナ以外の文字(平仮名・漢字・英数字・記号)が含まれていると登録できない' do @user.family_name_kana = 'ヤマダ' @user.valid? expect(@user.errors.full_messages).to include ('Family name kana カナは全角カタカナでお願いします。') end it '名(カナ)にカタカナ以外の文字(平仮名・漢字・英数字・記号)が含まれていると登録できない' do @user.first_name_kana = 'タロウ' @user.valid? expect(@user.errors.full_messages).to include('First name kana カナは全角カタカナでお願いします。') end end end end
user.rb
バリデーション全体
class User < ApplicationRecord devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable has_many :items with_options presence: true do validates :nickname validates :birthday end with_options presence: true, format: { with: /\A[ぁ-んァ-ヶ一-龥々ー]+\z/u, message: "氏名は全角でお願いします。" } do validates :family_name validates :first_name end with_options presence: true, format: { with: /\A[ァ-ヴー]+\z/u, message: "カナは全角カタカナでお願いします。" } do validates :family_name_kana validates :first_name_kana end validates :password, format: { with:/\A(?=.*[a-z])(?=.*\d)[a-z\d]\z/i,message:"パスワードは英数字混合の6文字以上です。"} end
試したこと
@user.save
another_user = FactoryBot.build(:user, email: @user.email)
another_user.valid?
expect(another_user.errors.full_messages).to include('Email has already been taken')
などに変更したりしましたが、変わらず…
補足情報(FW/ツールのバージョンなど)
Rails 7.0.8
「該当のソースコード」のパスワード関連の部分も見せてください (すでに回答があるようにパスワードバリデーションが作動しているためのような気がしますが……)。
パスワードのテストコードです。
it "passwordが空では登録できない" do
@user.password = ''
@user.valid?
expect(@user.errors.full_messages).to include("Password can't be blank")
end
it 'passwordが5文字以下では登録できない' do
@user.password = '12345'
@user.password_confirmation = '12345'
@user.valid?
expect(@user.errors.full_messages).to include('Password is too short (minimum is 6 characters)')
end
it 'passwordが129文字以上では登録できない' do
@user.password = Faker::Internet.password(min_length: 129, max_length: 150)
@user.password_confirmation = @user.password
@user.valid?
expect(@user.errors.full_messages).to include('Password is too long (maximum is 128 characters)')
end
it 'passwordとpassword_confirmationが不一致では登録できない' do
@user.password = '123456'
@user.password_confirmation = '1234567'
@user.valid?
expect(@user.errors.full_messages).to include("Password confirmation doesn't match Password")
end
バリデーション全体です。
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :items
with_options presence: true do
validates :nickname
validates :birthday
end
with_options presence: true, format: { with: /\A[ぁ-んァ-ヶ一-龥々ー]+\z/u, message: "氏名は全角でお願いします。" } do
validates :family_name
validates :first_name
end
with_options presence: true, format: { with: /\A[ァ-ヴー]+\z/u, message: "カナは全角カタカナでお願いします。" } do
validates :family_name_kana
validates :first_name_kana
end
validates :password, format: { with:/\A(?=.*[a-z])(?=.*\d)[a-z\d]\z/i,message:"パスワードは英数字混合の6文字以上です。"}
end
このコメント欄ではなく、質問文を編集して書いてください。
なお、コードの各部をばらばらに抜き書きするのではなく、他のテストコードとのつながりがわかるようにして欲しいです。今指摘されているのは「emailのテストをする際にpasswordのテストも作動しているのではないか」ということですから、全体としてそうなってしまうようなコードになっていないか確かめたいのです。
失礼しました。
明らかに、user.rbの最後のvalidationにパスワードが引っかかっています。テストは記述した通りに動作していると思います。
・個人的には /\A(?=.*[a-z])(?=.*\d)[a-z\d]\z/i でどんなパターンを検査しようとしているのか分からないです。パスワードのパターンに先読み正規表現など必要でしょうか。この正規表現はどんな文字列にもマッチしないと思います。

回答2件
あなたの回答
tips
プレビュー