2016-04-13 15 views
0

ich bin mit dem testen und es ist nicht genau klar, wenn ich let verwenden sollte.rspec modell spec lassen vs fabrik

Sollte ich let im folgenden Modell Test für Lazy Loading verwenden oder da die Daten in jedem Test etwas anders sind, kann ich es so behalten wie es ist? Wie ich in einigen Beispielen gesehen habe, ist es viel wichtiger für Controller-Tests, da die :task für jeden Aktionstest gleich sein würde.

Modell spec

require 'rails_helper' 

RSpec.describe Task, type: :model do 

    describe "model validations" do 

    it "has a valid factory" do 
     expect(build(:task)).to be_valid 
    end 

    it "is invalid without executor" do 
     expect(build(:task, executor_id: nil)).not_to be_valid 
    end 

    it "is invalid without assigner" do 
     expect(build(:task, assigner_id: nil)).not_to be_valid 
    end 

    it "is invalid without content" do 
     expect(build(:task, content: nil)).not_to be_valid 
    end 

    it "is invalid without deadline" do 
     expect(build(:task, deadline: nil)).not_to be_valid 
    end 

    it "is invalid with deadline in the past" do 
     expect(build(:task, deadline: Faker::Time.between(DateTime.now - 1, DateTime.now - 2))).not_to be_valid 
    end 
    end 
end 

Fabriken

FactoryGirl.define do 
    factory :task do 
    content { Faker::Lorem.sentence } 
    deadline { Faker::Time.between(DateTime.now + 2, DateTime.now + 3) } 
    association :executor, factory: :user 
    association :assigner, factory: :user 
    end 
end 

Antwort

1

Die Vorteile von let stammen aus Tests, die nicht von der Form sind Sie oben verwenden. Stellen Sie sich diese Gruppe vor:

Durch die späte Bindung können Sie minimale Änderungen vornehmen, aber maximale Abdeckung bieten. Je mehr Mitarbeiter Sie benötigen, um das für Ihre Tests erforderliche Verhalten einzurichten, desto eher profitieren Sie von let. Während Sie versuchen, DRY in Ihrer Testsuite nicht unbedingt zu fahren, sind riesige Setup-Blöcke für Ihre Tests ein Geruch, und die let-Technik ist ein großartiges Werkzeug, um Klarheit und Einfachheit zu gewährleisten, selbst wenn Ihre Domäne komplex ist . Mein eigenes Beispiel enthält noch keine Mitarbeiter, aber hoffentlich ist das Konzept noch klar genug.

+0

Jim, können Sie auch kopieren Dieser Code mit der Fabrik, um genau den Unterschied zu sehen? –

+0

@SzilardMagyar Fabriken erreichen ein ganz anderes Ziel. Die Aufgabe einer Factory besteht darin, Domänenobjekte bereitzustellen (und sie möglicherweise in der Datenbank zu belassen). Diese Strophe von Tests, die Sie oben schreiben, ist im Wesentlichen identisch mit denen, die ich für jedes aussagekräftige Modell in einer meiner Apps schreibe. Meine 'let'-Anweisungen enthalten häufig entweder Factory-Ausgaben selbst oder Domain-Methoden, die auf Objekten aufgerufen werden, die von einer Factory erstellt wurden. Ich hoffe, das hilft! –

+0

Jim, zum Beispiel sehe ich nicht, dass Sie die 'task' von' let (: task) {create (: not_due_task)}} oder von 'let (: task) {create (: overdue_task)}} verwenden, also don ' t Ihr Beispiel wirklich bekommen. –

1

ich es empfehlen würde zu halten, wie Sie es haben und nicht ein let verwenden. Mach dir keine Sorgen über DRYing Ihre Tests. Sie interagieren nicht miteinander, und so stoßen Sie nicht auf die Probleme, die bei der Code-Duplizierung in der Anwendungslogik auftreten würden.

Für was es wert ist, können Sie die shoulda-matchers Juwel verwenden können, um zu erreichen, was hast du da: https://github.com/thoughtbot/shoulda-matchers

describe Task do 
    describe "validations" do 
    it { is_expected.to validate_presence_of(:content) } 
    it { is_expected.to validate_presence_of(:deadline) } 
    end 
end 
+0

Nick, ich benutze s ofa Matcher nur nicht den Code hier kopieren. Soweit ich weiß, überprüfen diese nur die Existenz der Validierung. Mit diesem Code möchte ich sicherstellen, dass meine Fabrik und mein Objekt einwandfrei funktionieren. –

+0

@SzilardMagyar 'shofatimatchers' überprüft in den meisten Fällen die Werte, nicht das Vorhandensein der Validierung. Wenn Sie zum Beispiel "validate_presence_of" verwenden, können Sie den integrierten Rails-Präsenzvalidierer überspringen und ihn selbst neu erstellen ('errors.add (: content," kann nicht leer sein ") if content.blank?') . und der shofa Matcher würde funktionieren wie erwartet. Sie können in der Quelle sehen, dass es gegen tatsächliche leere Werte überprüft: https://github.com/thoughtbot/shoulda-matchers/blob/master/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb – Nick

Verwandte Themen