前提・実現したいこと
RSpecでテストを書いています。FactoryBotでユーザーを生成しているのですが、テストを実行すると実行した範囲内で一番最初のユーザーだけがメールアドレスが重複しているとのバリデーションエラーが発生してしまうので解決方法が知りたいです。
発生している問題・エラーメッセージ
Failure/Error: let(:user) { FactoryBot.create(:user) } ActiveRecord::RecordInvalid: バリデーションに失敗しました: メールアドレスはすでに存在します
該当のソースコード
ファクトリではemailを重複させないようにとシークエンスを使っています。
factory
1FactoryBot.define do 2 factory :user do 3 name { "factory" } 4 sequence(:email) { |n| "factory#{n}@example.com" } 5 password { "password" } 6 password_confirmation { "password" } 7 end 8end
テストコードは例としてspec/system/login_spec.rb
を記載します。
テストファイルはloginやらeditやら複数ありますが、どのファイルでも下に記載したようにlet(:user) { FactoryBot.create(:user) }
でユーザーをdbに作ってログインさせています。
login
1require 'rails_helper' 2 3RSpec.describe "User edit", type: :system do 4 let(:user) { FactoryBot.create(:user) } 5 6 describe "as a authenticated user" do 7 before do 8 login(user) #モジュールで定義 9 end 10 11 it "blabla ..." do 12. 13. 14.
試したこと
どんな範囲でテストしても、FactoryBot.create(:user)
でユーザーを生成したテストの中で、最初のテストだけがメールアドレス重複のバリデーションエラーになります。
例1. spec/system
の範囲をテストすると一番上のedit_spec.rb
の最初のテストだけエラー、他はパス
例2. spec/system/login_spec.rb
だけをテストするとlogin_spec.rb
の最初だけエラー、他はパス
以上のような具合です。
いろいろ調べた結果、Database Cleaner
というgemを使ってテスト実行時に作成したデータをテスト終了時に削除すれば良いのではないかと思ったのですが、さらに調べたところFeature spec
とは違いSystem spec
ではDatabase Cleaner
などを使ってロールバックを手動で設定する必要がないとのことだったので行き詰まってしまいました。
なのでおそらく原因は、そもそもFactoryBot
の使い方を間違っているか、テストファイルの記述が間違っているのだと思っています...
それともこのようなテストをする場合はFakerを使うべきなのでしょうか...?
補足情報(FW/ツールのバージョンなど)
環境は以下の通りです。
Mac OS Catalina 10.15.7
Ruby 2.7.1
Rails 6.0.3.3
RSpec 3.9
Factory_Bot 6.1.0
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。