2013-10-06 8 views
9

Ogni volta che eseguo un test utente, RSpec lascia l'utente fabbricato nel database di test dopo che il test è stato completato, il che sta rovinando i miei altri test. Farò un rake db:test:prepare, ma quando eseguo nuovamente i miei test, il record viene ricreato nel mio database. Non ho idea del perché stia succedendo. Succede solo con oggetti utente.RSpec lascia il record nel database di test

Nel mio file spec_helper ho anche:

config.use_transactional_fixtures = true 

Ecco un test di esempio che crea un record:

it "creates a password reset token for the user" do 
    alice = Fabricate(:user) 
    post :create, email: alice.email 
    expect(assigns(alice.password_reset_token)).to_not eq(nil) 
end 

Serramentista:

Fabricator(:user) do 
    email { Faker::Internet.email } 
    password 'password' 
    name { Faker::Name.name } 
end 

Questo potrebbe avere qualcosa a che fare con il mio modello di utenti?

risposta

0

Se dovessi indovinare, la linea post :create, email: alice.email sembra un probabile candidato per eseguire la creazione dell'utente.

Arrestare l'allineamento con un test fittizio e verificare se si sta ancora ottenendo un utente creato nel DB.

4

Ogni test è racchiuso in una transazione di database. Ciò significa che tutto ciò che viene creato durante il test dovrebbe essere eliminato al termine del test. Pertanto, sospetto che qualunque cosa tu abbia nel tuo database sia stata creata al di fuori del test stesso (come in un blocco before(:all)).

Inoltre, questo non garantisce che il database sarà vuoto ogni volta che si eseguono i test. Potrebbe essere possibile che tu abbia accidentalmente aggiunto un record in qualche modo, e ora continua a tornare a quello stato.

Se si desidera assicurarsi che i test abbiano un database lucido ogni volta, si dovrebbe dare un'occhiata alla gemma database_cleaner.

+0

Molto vecchio post lo so, ma attualmente sto avendo problemi con i dati di essere cancellati dal mio database (un progetto di eredità che ho preso. Per essere chiari stai dicendo che qualcosa dentro, "prima: tutto fa ... fine" non è transazionale? Perché dovrebbe essere così e oggi mi sono grattato la testa per un giorno, la documentazione è molto limitata su questo.per esempio, questo codice include 'before: all do User.delete_all end'. Modifica: Ok appena trovato, questo (https://relishapp.com/rspec/rspec-rails/docs/transactions). wow, il tempo di refactoring molto codice ... al fine di ottenere il mio compito originale fatto grrr! – wired00

17

si dovrebbe usare una gemma chiamata database_cleaner che troncherà il database e resettare tutto automaticamente in modo nel file gemma aggiungere il database_cleaner gemma dopo che all'interno della vostra spec_helper.rb configurarlo

spec_helper.rb

config.use_transactional_fixtures = false 

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

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

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

e quindi creare un nuovo file nella directory spec/supporto

spec/supporto/shared_db_connection.rb

classActiveRecord::Base 
    mattr_accessor :shared_connection 
    @@shared_connection = nil 

    def self.connection 
    @@shared_connection || retrieve_connection 
    end 
end 
ActiveRecord::Base.shared_connection=ActiveRecord::Base.connection 

Ora ogni volta che si esegue i test il database sarà reset.This è stata presa dal libro 'quotidiane Rails test con RSpec' di Aaron Sumner

+0

questa è la soluzione corretta/praticabile –

+0

infatti è la soluzione corretta – Hamdan

+1

Si prega di aggiornare, dovrebbe leggere 'classe ActiveRecord :: Base' – kingPuppy

1

La soluzione più semplice è quello di assicurarsi RSpec test eseguiti nelle transazioni (Rails fa questo per default)

spec_helper.rb

config.around(:each) do |example| 
    ActiveRecord::Base.transaction do 
    example.run 
    raise ActiveRecord::Rollback 
    end 
end 
Problemi correlati