Was ist der Unterschied zwischen den Erstellungs- und Erstellungsmethoden in FactoryGirl?

94

Die Einführung von Factory Girl beschreibt den Unterschied zwischen FactoryGirl.build()und FactoryGirl.create():

# Returns a User instance that's not saved
user = FactoryGirl.build(:user)

# Returns a saved User instance
user = FactoryGirl.create(:user)

Ich verstehe die praktischen Unterschiede zwischen den beiden immer noch nicht. Kann jemand ein Beispiel geben, wo Sie das eine und nicht das andere verwenden möchten? Vielen Dank!

Avery
quelle

Antworten:

115

Die create()Methode build()behält die Instanz des Modells bei, während die Methode sie nur im Speicher behält.

Persönlich verwende ich die create()Methode nur, wenn Persistenz wirklich notwendig ist, da das Schreiben in DB das Testen zeitaufwändig macht.

z.B

Ich erstelle Benutzer für die Authentifizierung, create()da meine Authentifizierungs-Engine die Datenbank abfragt.

Um zu überprüfen, ob ein Modell ein Attribut hat, führt die build()Methode aus, dass kein DB-Zugriff erforderlich ist.

it{Factory.build(:user).should respond_to(:name)}

Aktualisieren

"Es gibt eine Ausnahme, die Build tatsächlich" erstellt ", wenn Sie Assoziationen erstellen, dh Ihre Assoziation befindet sich nicht mehr im Speicher, sondern bleibt bestehen. Denken Sie daran" - Shakes

Helio Santos
quelle
14
Es gibt eine Ausnahme, die der Build tatsächlich erstellt, wenn Sie Assoziationen erstellen, dh Ihre Assoziation befindet sich nicht mehr im Speicher, sondern bleibt bestehen. Denken Sie daran
Shakes
@Shakes, ich arbeite nicht mehr in Schienen. Ich werde das überprüfen, sobald ich kann.
Helio Santos
Hat jemand ein Tool erstellt, mit dem jede Instanz createdurch ersetzt buildund rückgängig gemacht werden kann, wenn der Test fehlschlägt?
mgold
Liest #createund speichert das persistierte Objekt von der Festplatte oder gibt es das Objekt zurück, das sich nach dem Persistieren im Speicher befindet? Mit anderen Worten, ist das create(...)gleichbedeutend mit create(...).reload?
Dennis
@mgold Vim ist ziemlich gut in so etwas.
Begrenzte Versöhnung
15

Die Verwendung FactoryGirl.build(:factory_name)bleibt für die Datenbank nicht bestehen und wird nicht aufgerufen save!, sodass Ihre Active Record-Überprüfungen nicht ausgeführt werden. Dies ist viel schneller, aber Validierungen können wichtig sein.

Die Verwendung FactoryGirl.create(:factory_name)bleibt in der Datenbank bestehen und ruft Active Record-Validierungen auf. Dies ist offensichtlich langsamer, kann jedoch Validierungsfehler auffangen (wenn Sie diese in Ihren Tests berücksichtigen).

Kluft
quelle
11
Oder könnten Sie einfach FactoryGirl.build (: factory_name) .valid ausführen? die Validierungen ausführen, ohne in der Datenbank zu speichern.
Jinavar1
1

FactoryGirl.create()erstellt ein neues Objekt und neue Assoziationen (falls vorhanden). Sie werden alle in einer Datenbank gespeichert. Außerdem werden sowohl Modell- als auch Datenbanküberprüfungen ausgelöst. Rückrufe after(:build)und after(:create)werden aufgerufen, nachdem die Fabrik gespeichert wurde. Auch before(:create)genannt werden , bevor die Fabrik gespeichert wird.

FactoryGirl.build()speichert kein Objekt, stellt jedoch weiterhin Anforderungen an eine Datenbank, wenn die Factory über Zuordnungen verfügt. Es werden nur Überprüfungen für zugeordnete Objekte ausgelöst. Rückruf after(:build)wird nach dem Bau der Fabrik aufgerufen.

Beachten Sie, dass in den meisten Fällen beim Testen Modelle am besten build_stubbedfür eine bessere Leistung verwendet werden können. Lesen Sie hier mehr darüber .

Nesha Zoric
quelle