Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create/build multiple instances of a factory in Factory Girl?

How do I create multiple records or multiple factories of the same class?

I tried:

Factory.define :user do |user|   user.email "[email protected]"   user.password "somepassword"    user.email "[email protected]"   user.password "somepassword" end 

and

Factory.define :user do |user|   user.email "[email protected]"   user.password "somepassword" end  Factory.define :user do |user|   user.email "[email protected]"   user.password "somepassword" end 

But it doesn't work -- Attribute already defined: email.

like image 670
benoitr Avatar asked Apr 01 '11 06:04

benoitr


People also ask

What is FactoryBot used for?

Factory Bot is often used in testing Ruby on Rails applications; where it replaces Rails' built-in fixture mechanism. Rails' default setup uses a pre-populated database as test fixtures, which are global for the complete test suite.

What is Build_stubbed?

build_stubbed is the younger, more hip sibling to build ; it instantiates and assigns attributes just like build , but that's where the similarities end.

What is FactoryBot in Rspec?

Factory Bot is a helper for writing factories for Ruby tests. It was previously known as Factory Girl. For older versions, use FactoryGirl instead of FactoryBot . Factory Bot documentation (rubydoc.info) Getting started (github.com)


2 Answers

This is an older question and answer but it was the first result I found on Google so I thought I would add the following from the docs under the heading Building or Creating Multiple Records:

created_users = FactoryBot.create_list(:user, 25)  #creates 25 users  twenty_year_olds = FactoryBot.build_list(:user, 25, date_of_birth: 20.years.ago)  #builds 25 users, sets their date_of_birth 

If you want to run this in the rails console, consider the following answer here: https://stackoverflow.com/a/23580836/4880924

In the example I just cited, each user would have a different username, provided that sequence is used in the factory definition (see Mike Lewis' answer above).

like image 126
aceofbassgreg Avatar answered Sep 30 '22 13:09

aceofbassgreg


There's a couple of options if you want records from the same (base) factory to have different values.

A) Override defined attributes

factory :post, aliases: [:approved_post] do   title "A title"   approved true end  approved_post = create(:approved_post) unapproved_post = create(:post, approved: false) 

B) Inheritance

factory :post do   title "A title"    factory :approved_post do     approved true   end    factory :unapproved_post do     approved false   end end  approved_post = create(:approved_post) unapproved_post = create(:unapproved_post) 

C) Sequences

factory :user do   sequence(:email, 1000) { |n| "person#{n}@example.com" } end 

D) Traits

factory :post do   title "My awesome title"    trait(:approved) { approved true }    trait(:unapproved) { approved false }    trait :with_comments do     after(:create) do |instance|       create_list :comment, 2, post: instance     end   end    factory :approved_post_with_comments, traits: [:approved, :with_comments] end  approved_post_with_comments = create(:approved_post_with_comments) unapproved_post_with_no_comments = create(:post, :unapproved, title: "Test") post_with_title = build(:post) 

These methods can be combined. This example uses lists and pairs with sequences and overriding.

factory :user do   sequence(:username) { |n| "user#{n}" }   date_of_birth Date.today end  # Build a pair and a list of users. two_newborns     = build_pair(:user) ten_young_adults = build_list(:user, 10, date_of_birth: 20.years.ago)  # Create a pair and a list of users. two_young_adults = create_pair(:user, date_of_birth: 20.years.ago) ten_newborns     = create_list(:user, 10) 

I prefer to use traits whenever possible, I find them flexible.

like image 37
Dennis Avatar answered Sep 30 '22 12:09

Dennis