2010-10-04 4 views
32

Wie deaktiviere ich transaktionale Fixtures für nur eine Spec (oder Steak-Szenario) mit RSpec 2? Ich habe einige Dinge im Internet ohne Erfolg versucht.Transaktionäre Fixtures für eine Spec mit RSpec deaktivieren 2

Dies führt zu einer nicht definierten Methodenausnahme.

 
describe "MyClass without transactional fixtures" do 
    self.use_transactional_fixtures = false 
    ... 
end 

Dieses einfach nichts tut (Transaktionsbefestigung noch eingeschaltet ist):

 
describe "MyClass without transactional fixtures" do 
    RSpec.configure do |config| 
    config.use_transactional_fixtures = false 
    end 
    ... 
end 

Was könnte ich versuchen?

+0

ist es wirklich verdrahtet, das zu wollen. weil Sie nicht wissen können, was Sie in Ihrer Datenbank haben. – shingara

+0

Ich hoffe, das stimmt auch nicht für deinen Code ;-) Aber im Ernst, für einige Testszenarien musst du die transaktionalen Fixtures deaktivieren. Zum Beispiel, wie in meinem Fall, Thinking Sphinx zu testen. Sphinx muss den Suchindex von "draußen" aktualisieren. Daher muss der Datenbankinhalt zu einem bestimmten Zeitpunkt bekannt sein. – Zardoz

+0

Nur eine Sache zu beachten; Zumindest in meiner Umgebung (Rails4 rspec 2), wenn Sie aus irgendeinem Grund die rspec/rails_helper in einer Ihrer RSPEC-Dateien enthalten, wird jeder Test danach in der Suite oder in nachfolgenden Dateien erneut ausgeführt. –

Antwort

7

Das war mal ein Bug (siehe ticket #197), aber ich scheint jetzt in Ordnung zu sein. Ich weiß nur nicht, ob es auf einer Testbasis funktionieren wird (wahrscheinlich nicht). Wenn Sie dies tun möchten, können Sie transaktionale Fixtures global deaktivieren, indem Sie config.use_transactional_fixtures = false auf spec_helper.rb setzen und DatabaseCleaner verwenden, um das festzulegen.

Ich hatte ein ähnliches Problem beim Testen von Seiten mit Javascript im Browser (ein Szenario, das nicht mit transaktionalen Fixtures funktioniert). Hier ist, wie ich es geschafft, um es an die Arbeit: http://github.com/lailsonbm/contact_manager_app

+1

Danke für das Zeigen auf das Ticket, Lailson. Antwort akzeptiert :-) Ich benutze auch einen Workaround, da ich transaktionale Fixtures nicht global deaktivieren möchte (zu langsam). Ich mache einfach eine MyClass.connection.commit_db_transaction(), nachdem die Objekte erstellt wurden. Dann mache ich den Test und lösche anschließend die Datenbankeinträge. Das funktioniert gut, und alle anderen Tests verwenden weiterhin die Transaktionsfunktion. – Zardoz

+0

Schön. Wie ich schon sagte, können Sie dies sauber mit DatabaseCleaner tun (siehe die README von github repo, auf die ich hingewiesen habe, um zu wissen, wie das geht).Aber Ihre Lösung ist auch machbar, nur ein wenig fehleranfällig. Aber wenn es funktioniert und du zufrieden bist, cool ... =) –

+0

Ich habe 'MyClass.connection.commit_db_transaction' versucht, aber es hat die Verbindung in einem ungeraden Zustand verlassen, in dem es dachte, dass es eine offene Transaktion hatte, aber es tat es nicht. Dies führte dazu, dass bestimmte aktive Aufzeichnungsbefehle nicht funktionierten und auch zu Warnungen führten. Dies schien das Problem zu beheben, tatsächlich die Transaktion in der db zu schließen und die Verbindung zu aktualisieren, um zu wissen, dass es keine offene Transaktion mehr hatte: MyClass.connection..transaction_manager.commit_transaction – nbrustein

25

ich in der Regel einen Helfer wie folgt hinzu:

def without_transactional_fixtures(&block) 
    self.use_transactional_fixtures = false 

    before(:all) do 
    DatabaseCleaner.strategy = :truncation 
    end 

    yield 

    after(:all) do 
    DatabaseCleaner.strategy = :transaction 
    end 
end 

Was mich Transaktionsvorrichtungen für einen bestimmten Block in den Spezifikationen ausschalten lässt:

describe "doing my thing" do 
    without_transactional_fixtures do 
    it "does something without transaction fixtures" do 
     ... 
    end 
    end 
end 
+0

Sind Sie sicher, dass es funktioniert? Ich habe hier versucht, etwas zu testen, das Schienen Transaktionen verwendet und nicht funktioniert :( – Guilherme

+2

Sie können nur die DatabaseCleaner.Strategy in einem Vorher/Nachher-Block Ihrer Spezifikationen zu ändern. –

7

Ich habe es so gemacht, mit database_cleaner, um Code zu testen, der Transaktionen verwendet (die in Konflikt mit transactional_fixtures oder einer anderen Strategie stehen, um Transaktionstests zu machen zB DatabaseCleaner.strategy =: truncation oder: transaction):

# spec_helper.rb 
config.use_transactional_fixtures = false 
config.around(:each, :testing_transactions => true) do |ex| 
    DatabaseCleaner.strategy = nil 
    ex.run 
    DatabaseCleaner.strategy = :truncation 
end 

und in meinem Testfall:

it "should not save if one of objects are invalid", :testing_transactions => true 
0

nicht sicher, ob das zu RSpec2 gilt, sondern arbeitet mit 3.

config.use_transactional_fixtures = true 
config.around(:each, use_transactional_fixtures: false) do |example| 
    self.use_transactional_tests = false 
    example.run 
    self.use_transactional_tests = true 
end 

Mind the use_transactional_fixtures (rspec-Schienen-Option) fein und use_transactional_tests (activerecord fixtures option) Unterschied.