2013-01-16 5 views
10

Wie Sie die Objekte löschen (in der Datenbank und im Speicher) Sie erstelltRSpec: Flush Tabelle/zerstören Objekte nach jedem Kontext

  • nach jedem Test
  • und nach jedem Kontext? (In einem Kontext könnte es sinnvoll sein, Tests miteinander zu erstellen)

Gibt es eine Methode, dies automatisch zu tun?

Ich habe folgendes Problem:

Jeder Test speichert Einträge in die Datenbank. Der nächste Test hängt dann von diesen Einträgen ab. Auch wenn ich Tests erstellen wollte, die von anderen Tests abhängig sind, konnte ich das nicht, weil die Reihenfolge, in der die Tests ausgeführt werden, nicht kontrollierbar ist.

factories.rb:

sequence(:name) { |n| "purchaser #{n}" }  

organization_spec.rb:

context "when no supplier exists" do 
    it "finds no associated suppliers" do 
    purchaser = create(:organization_purchaser)     
    purchaser.partners.empty?.should == true 
    end 
end 

context "when one supplier exists" do 
    it "finds one associated suppliers" do 
    purchaser = create(:organization_purchaser)  
    supplier = create(:organization_supplier) 
    partnership = create(:partnership, organization: purchaser, partner: supplier)   
    purchaser.partners.last.name.should == "purchaser 1" 
    end 
end 

context "when two suppliers exist" do   
    it "finds two associated suppliers" do 
    purchaser = create(:organization_purchaser)  
    2.times do |i| 
     supplier = create(:organization_supplier) 
     partnership = create(:partnership, organization: purchaser, partner: supplier) 
    end  
    purchaser.partners.last.name.should == "purchaser 2" 
    end 
end 

RSpec Ausgang:

Organization 
    #suppliers_for_purchaser 
    responds 
    when no supplier exists 
     finds no associated suppliers 
    when two suppliers exist 
     finds two associated suppliers 
    when one supplier exists 
     finds one associated suppliers (FAILED - 1) 

Failures: 

1) Organization#suppliers_for_purchaser when one supplier exists finds one associated suppliers 
Failure/Error: purchaser.partners.last.name.should == "purchaser 1" 
    expected: "purchaser 1" 
     got: "purchaser 3" (using ==) 
+2

https://github.com/bmabey/database_cleaner – deefour

Antwort

15

Sie sollten verwenden Database Cleaner

Alles, was Sie tun müssen, ist die folgenden c hinzufügen Ode an Ihre Rspec Konfigurationsdatei spec_helper.rb

config.before(:suite) do 
    DatabaseCleaner.strategy = :transaction 
    DatabaseCleaner.clean_with(:truncation) 
end 

config.before(:each) do 
    DatabaseCleaner.start 
end 

config.after(:each) do 
    DatabaseCleaner.clean 
end 

UPDATE

Ab Rails 5.1 dies nicht, wenn Sie config.use_transactional_tests

verwenden benötigt wird

https://github.com/rails/rails/pull/19282

6

Haben Sie versucht, eine Zugabe vor der Methode?

1

Ich denke, deine Frage ist mehr in Richtung wie kann ich eine Factory Girl-Sequenz zurücksetzen? Diese sind nicht in der Datenbank gespeichert, selbst wenn Sie alles löschen, wird das Problem weiterhin bestehen. Wenn so etwas wie dies zu testen ich es easer nur die Fabrik Mädchen Folge außer Kraft setzen zu finden ..

it "finds one associated suppliers" do 
    purchaser = create(:organization_purchaser)  
    supplier = create(:organization_supplier , name: "My First Supplier") 
    partnership = create(:partnership, organization: purchaser, partner: supplier)   
    purchaser.partners.last.name.should == "My First Supplier" 
    end 

Die anderen Dinge, die Sie wahrscheinlich tun, ist so etwas wie

it "finds one associated suppliers" do 
     purchaser = create(:organization_purchaser)  
     supplier = create(:organization_supplier) 
     partnership = create(:partnership, organization: purchaser, partner: supplier)   
     purchaser.partners.last.should == supplier 
     end 

oder sogar

it "finds one associated suppliers" do 
     purchaser = create(:organization_purchaser)  
     supplier = create(:organization_supplier) 
     partnership = create(:partnership, organization: purchaser, partner: supplier)   
     purchaser.partners.last.name.should == supplier.name 
     end