Domanda

Ho cercato di risolvere un problema per un paio di settimane. Sono in esecuzione test RSpec per il mio Rails app, e stanno bene, tranne per un errore che non posso sembrare ottenere la mia testa intorno lavorando.

  • Sto usando MySQL con il motore InnoDB.
  • Ho impostato config.use_transactional_fixtures = true in spec_helper.rb
  • carico le mie attrezzature di prova manualmente con il comando rake spec:db:fixtures:load.
  • Il test RSpec è stato scritto per un lavoratore BackgrounDRb, e sta testando che un record può avere il suo stato aggiornato (tramite la gemma state_machine).

Ecco il mio problema:

Ho un modello chiamato Listings. Il test RSpec chiama il metodo update_sold_items all'interno di un file chiamato listing_worker.rb. Questo metodo chiama listing.sell per un particolare record, che definisce colonna 'Stato' del record annuncio nei miei 'venduto'. Finora, questo è tutto funziona bene, ma quando il metodo update_sold_items finisce, il mio test RSpec fallisce qui:

listing = Listing.find_by_listing_id(listing_id)
listing.state.should == "sold"

expected: "sold",
     got: "current" (using ==)

Ho cercato di rintracciare il motivo per cui il cambiamento di stato non è persistente, ma sto praticamente perso. Ecco il risultato di un codice di debug che ho messo nel metodo update_sold_items durante il test:

pp listing.state  # => "current"

listing.sell!
listing.save!

pp listing.state  # => "sold"

listing.reload

pp listing.state  # => "current"

Non riesco a capire il motivo per cui si salva perfettamente bene, ma poi ritorna al record originale ogni volta che io chiamo reload o Listing.find ecc.

Grazie per la lettura di questo, e prego tutte le domande se non ho dato abbastanza informazioni.

Grazie per il vostro aiuto, Nathan B

P.S. Non ho un problema la creazione di nuovi record per le altre classi, e testare i record. Sembra solo per essere un problema quando sto aggiornando i record che già esistono nel database.

È stato utile?

Soluzione

Ho il sospetto, come Nathan, problemi di transazione. Prova a mettere un Listing.connection.execute ( "commit") a destra prima della prima salvare chiamare a rompere la transazione e vedere cosa cambia. Che si romperà fuori della transazione in modo tutte le chiamate di rollback supplementari saranno non efficace.

Inoltre, eseguendo un comando "commit", si potrebbe mettere in pausa il test con un debugger e ispezionare il database da un altro client per vedere cosa sta succedendo.

L'altra ipotesi, se la sperimentazione operazione non produce alcun risultato, è che forse il vostro modello in realtà non sta risparmiando al database. Controllare i log delle query. (In particolare trovare la query di aggiornamento).

Questo tipo di problemi davvero puzza! In bocca al lupo!

Altri suggerimenti

Se si vuole indagare su quello che hai in DB durante l'esecuzione di test si potrebbe trovare questo utile ...

Ho un test di rspec dove li risparmio @ user.save e funziona come un fascino, ma poi ho voluto vedere se è davvero salvato nel DB.

Ho aperto console rotaie per ambiente di test

rails c test

Ran

User.all

e come previsto non ha ottenuto nulla

Ho corso la mia spec che contiene:

user_attr_hash    = FactoryGirl.attributes_for(:user)
@user = User.new user_attr_hash
@user.save
binding.pry

Ho pensato che fermare il test dopo salvare significherebbe che è persisteva, ma non è questo il caso. Sembra che si impegnano per la connessione viene licenziato dopo (non ho idea di quando: \) Così, come suggerisce @ Tim Harper, si deve sparare che impegnarsi nella console leva:

pry(#<RSpec::Core::ExampleGroup::Nested_1>)> User.connection.execute("COMMIT")

Ora, se si esegue User.all nelle rotaie consolare si dovrebbe vedere;)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top