28 Stimmen

Wie kann man mehrere Instanzen einer Fabrik in Factory Girl erstellen/erstellen?

Wie kann ich mehrere Datensätze oder mehrere Fabriken der gleichen Klasse erstellen?

Ich habe es versucht:

Factory.define :user do |user|
  user.email "someuser@somesite.com"
  user.password "somepassword"

  user.email "another_existing_user@somesite.com"
  user.password "somepassword"
end

et

Factory.define :user do |user|
  user.email "someuser@somesite.com"
  user.password "somepassword"
end

Factory.define :user do |user|
  user.email "another_existing_user@somesite.com"
  user.password "somepassword"
end

Aber es funktioniert nicht. Attribute already defined: email .

49voto

aceofbassgreg Punkte 3699

Dies ist eine ältere Frage und Antwort, aber es war das erste Ergebnis, das ich bei Google gefunden habe, so dass ich dachte, ich würde das Folgende aus der docs unter der Rubrik Mehrere Datensätze erstellen oder anlegen :

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

Wenn Sie dies in der Rails-Konsole ausführen möchten, beachten Sie die folgende Antwort hier: https://stackoverflow.com/a/23580836/4880924

In dem soeben angeführten Beispiel würde jeder Benutzer einen anderen Benutzernamen haben, vorausgesetzt, dass sequence in der Fabrikdefinition verwendet wird (siehe die Antwort von Mike Lewis oben).

37voto

Dennis Punkte 51330

Es gibt mehrere Möglichkeiten, wenn Sie möchten, dass Datensätze aus derselben (Basis-)Fabrik unterschiedliche Werte haben.

A) Definierte Attribute außer Kraft setzen

factory :post, aliases: [:approved_post] do
  title "A title"
  approved true
end

approved_post = create(:approved_post)
unapproved_post = create(:post, approved: false)

B) Vererbung

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) Sequenzen

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

D) Eigenschaften

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)

Diese Methoden können kombiniert werden. In diesem Beispiel werden Listen und Paare mit Sequenzen und Overriding verwendet.

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)

Ich bevorzuge, wann immer möglich, die Verwendung von Merkmalen, da ich sie flexibel finde.

23voto

Mike Lewis Punkte 62061

Die Verwendung von Fabriken erfolgt in zwei Schritten: Der erste Schritt besteht darin, sie zu definieren, und der zweite darin, sie zu verwenden.

1) Definieren Sie sie:

Factory.define :user do |u|
  u.sequence(:email) { |n| "mike#{n}@awesome.com"}
  u.password "password123"
end

2) Sie zu benutzen:

Ein Beispiel wäre, sie in einer Spezifikation zu verwenden:

 @user1 = Factory(:user) #has an email of mike1@awesome.com
 @user2 = Factory(:user) # has an email of mike2@awesome.com due to sequences in FG

Ich würde mir das ansehen Eisenbahnsendung um ein besseres Gefühl dafür zu bekommen.

0voto

TNT Punkte 3072

Mit dem aktuellen factory_girl_rails 4.6.0 hatte ich das damit verbundene Problem, dass build(:model) immer die gleiche Instanz des Objekts zurück. Verwendung von sequence(:name) ... hat das nicht behoben. Also habe ich einige gefälschte (leere) Eigenschaften wie diese erstellt:

FactoryGirl.define do
  factory :model do
     ...
     # fake traits to urge factory_girl to always return a new instance:
    (1..5).each {|n| trait "var#{n}".to_sym }
  end
end

Und dann anrufen build(:model, :var1), build(:model, :var2)...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X