Beschleunigung von Assoziationen in Modellspezifikationen mit FactoryGirl - create vs build vs build_stubbed

8

Angenommen, ich habe die Modelle User und Post , einen Benutzer has_many Beiträge und einen Beitrag belongs_to einen Benutzer.

Wenn ich eine Spezifikation für Post schreibe, ist mein erster Instinkt, so etwas zu schreiben:

%Vor%

Aber das wird für jeden einzelnen Test einen neuen Benutzer schaffen - die Datenbank zu treffen -, der die Dinge verlangsamen wird. Gibt es einen besseren Weg, um meine Tests zu beschleunigen und zu vermeiden, die DB so oft zu treffen?

Wie ich es verstehe, kann ich FactoryGirl.build :user nicht verwenden, weil die Assoziationen nicht funktionieren werden, auch wenn sie nicht auf die DB treffen, weil @user keine ID hat und so @post.user funktioniert nicht (es gibt nil zurück.)

Ich könnte FactoryGirl.build_stubbed :user verwenden, was eine "fake persisted" @user erzeugt, die zwar eine ID hat, aber @post.user gibt immer noch nil zurück. Hat build_stubbed einen praktischen Vorteil gegenüber build , wenn ich Dinge im Zusammenhang mit Assoziationen teste?

Ich nehme an, ich könnte build_stubbed stub @post.user verwenden, damit es @user zurückgibt ... Gibt es einen Grund, warum das eine schlechte Idee sein könnte?

Oder soll ich einfach create verwenden und den Geschwindigkeits-Treffer akzeptieren?

Die einzige andere Alternative, die ich mir vorstellen kann, wäre, @user in einem before(:all) -Block einzurichten, was eine schlechte Idee zu sein scheint.

Was ist der beste Weg, um diese Art von Tests auf eine saubere, prägnante Weise zu schreiben, die vermeidet, zu viele DB-Abfragen zu machen?

    
GMA 18.12.2013, 16:28
quelle

4 Antworten

18

Wenn Sie nicht möchten, dass Ihre Tests die Datenbank treffen, müssen Sie dies tun.

%Vor%

Hinweis: Seien Sie vorsichtig, wenn Sie before(:all) verwenden. Es wird nicht in einer Transaktion ausgeführt. Was auch immer Sie in before(:all) erstellen, wird in der Datenbank zurückgelassen und kann zu Konflikten mit anderen Tests führen

Über FactoryGirl.build , es baut das Objekt auf, erstellt aber die Assoziationen.

Für zB:

%Vor%     
usha 18.12.2013, 16:34
quelle
15

Kurze Antwort

%Vor%

Damit wird @ post.user funktionieren, ohne jemals die Datenbank zu treffen.

Lange Antwort

Meine Empfehlung wäre, auf den before -Block zu warten, bis Sie sicher sind, dass Sie ihn brauchen. Erstellen Sie stattdessen die Daten, die Sie für jeden einzelnen Test benötigen, und extrahieren Sie die Duplizierung in Methoden oder neue Fabriken, wenn Sie sie finden.

Müssen Sie tatsächlich bei jedem einzelnen Test auf den Benutzer verweisen? Wenn @user in jedem Test zur Verfügung steht, sagen andere Entwickler, dass es überall wichtig ist.

Wenn Sie schließlich davon ausgehen, dass die Benutzerverknüpfung auch in Ihrer Post-Factory deklariert ist, erhalten Sie automatisch eine funktionierende post.user , wenn Sie build_stubbed(:post) ausführen.

    
Joe Ferris 18.12.2013 16:39
quelle
8

Es kann leicht sein, die Unterschiede zwischen create , build und build_stubbed zu vergessen. Hier finden Sie eine Kurzreferenz für Personen in derselben Situation (da diese Seite in den Suchergebnissen eine hohe Bewertung aufweist).

%Vor%

Quelle

    
Dennis 24.11.2014 17:01
quelle
1

Aus dem Dokument von Factory Girl können Sie die Strategie build für user in der Assoziation in post factory wie folgt identifizieren:

%Vor%

Damit können Sie build a post ohne speichern user

%Vor%     
Leo Le 06.10.2016 07:31
quelle