Question

J'ai essayé de résoudre un problème pendant quelques semaines. Je courais essais rspec pour mon application Rails, et ils fonctionnent très bien, sauf pour une erreur que je ne peux pas sembler obtenir ma tête.

  • J'utilise MySQL avec le moteur InnoDB.
  • J'ai mis config.use_transactional_fixtures = true dans spec_helper.rb
  • je charge mes appareils de test manuellement avec la commande rake spec:db:fixtures:load.
  • Le test rspec est en cours d'écriture pour un travailleur BackgrounDRb, et il teste qu'un enregistrement peut avoir son état mis à jour (par la gemme state_machine).

Voici mon problème:

J'ai un modèle appelé Listings. Le test rspec appelle la méthode update_sold_items dans un fichier appelé listing_worker.rb. Cette méthode appelle listing.sell pour un enregistrement particulier, qui définit la colonne « état » du dossier d'inscription à « vendu ». Jusqu'à présent, cela est fonctionne très bien, mais quand la méthode update_sold_items se termine, mon test échoue rspec ici:

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

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

J'ai essayé de retrouver la raison pour laquelle le changement d'état ne persiste, mais je suis à peu près perdu. Voici le résultat d'un code de débogage que j'ai placé dans la méthode update_sold_items lors du test:

pp listing.state  # => "current"

listing.sell!
listing.save!

pp listing.state  # => "sold"

listing.reload

pp listing.state  # => "current"

Je ne comprends pas pourquoi il sauve parfaitement bien, mais revient ensuite revenir à l'enregistrement d'origine chaque fois que j'appelle reload, ou Listing.find etc.

Merci d'avoir lu ceci, et s'il vous plaît poser des questions si je ne l'ai pas donné suffisamment d'informations.

Merci pour votre aide, Nathan B

P.S. Je n'ai pas de problème en créant de nouveaux enregistrements pour d'autres classes, et de tester ces enregistrements. Il semble seulement être un problème quand je suis mise à jour des documents qui existent déjà dans la base de données.

Était-ce utile?

La solution

Je pense, comme nathan, les problèmes de transaction. Essayez de mettre un Listing.connection.execute ( « Commit ») juste avant votre premier appel à sauver briser la transaction et voir quels changements. Cela vous sortir de la transaction afin d'appels d'annulation supplémentaires seront non efficaces.

En outre, en exécutant une commande « COMMIT », vous pouvez mettre en pause le test avec un débogueur et d'inspecter la base de données d'un autre client pour voir ce qui se passe.

L'autre hypothèse, si l'expérimentation de la transaction ne donne aucun résultat, est que peut-être votre modèle est vraiment pas sauver la base de données. Vérifiez vos journaux de requêtes. (Trouver précisément la requête de mise à jour).

Ce genre de questions pue vraiment! Bonne chance!

Autres conseils

Si vous voulez enquêter sur ce que vous avez dans DB pendant les tests, vous trouverez peut-il été utile ...

J'ai un test rspec où je sauve @ user.save et il fonctionne comme un charme, mais je voulais voir si elle est vraiment enregistré dans le DB.

J'ai ouvert console rails pour l'environnement de test

rails c test

RAN

User.all

et comme prévu rien obtenu

J'ai couru ma spec qui contient:

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

Je pensais que l'arrêt de l'essai après l'enregistrement, cela signifierait qu'il est persisté, mais ce n'est pas le cas. Il semble que COMMIT sur la connexion est congédié par la suite (je ne sais pas quand: \) Donc, comme Harper suggère @ Tim, vous devez tirer que Engagez-vous dans la console de levier:

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

Maintenant, si vous exécutez User.all dans vos rails console vous devriez le voir;)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top