LoginSignup
12
8

More than 3 years have passed since last update.

【RSpec】重複のバリデーションエラーを回避するFactoryBotの書き方

Last updated at Posted at 2020-02-05

ユーザー登録でemailを重複させないようにバリデーションをかけましが、テストのときにでFactoryBotで複数ユーザを予め生成する必要があったので方法を調べました。シーケンスを使ってユニークなデータを生成するやり方です。備忘録として残します。

問題点

ファクトリーで複数のユーザをセットアップする際に、emailをバリデーションでユニークなデータとして設定している場合、下記のようにするとテストコードが走る前に例外が発生します。

spec/factories/users.rb
FactoryBot.define do
  factory :user do
    user_name { "tester" }
    email { "tester@example.com" }
    password { "password" }
  end
end
spec/models/user_spec.rb
  it "複数のユーザー登録" do
    user1 = FactoryBot.create(:user)
    user2 = FactoryBot.create(:user)
  end

これでテストを実行すると、当然ですが次のようなバリデーションエラーが発生します。

ターミナル
Failures:
  1) 複数のユーザー登録
     Failure/Error: user2 = FactoryBot.create(:user)

     ActiveRecord::RecordInvalid:
       バリデーションに失敗しました: メールアドレスはすでに存在します

解決策

シーケンスを使います。シーケンスはファクトリから新しいオブジェクトを作成するたびにカウンタの値を1づつ増やしながら値を設定します。

spec/factories/users.rb
FactoryBot.define do
  factory :user do
    user_name { "tester" }
    sequence(:email) { |n| "tester#{n}@example.com" }
    password { "password" }
  end
end

email { "tester@example.com" }sequence(:email) { |n| "tester#{n}@example.com" }と書き換えることで、userが生成されるたびにが1づつ増えていき、tester1@example.comtester2@example.comのようにユニークで連続したemailが設定されます。

ターミナル
#見やすいように加工してあります
user1
<User id: 13, 
user_name: "tester", 
email: "tester1@example.com", 
password: "password", 
created_at: "2020-02-05 01:56:36", 
updated_at: "2020-02-05 01:56:36">
ターミナル
#見やすいように加工してあります
user2
<User id: 14, 
user_name: "tester", 
email: "tester2@example.com", 
password: "password",
created_at: "2020-02-05 01:57:21", 
updated_at: "2020-02-05 01:57:21">
12
8
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
12
8