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:
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?
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%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.
Tags und Links unit-testing ruby-on-rails factory-bot rspec