2010-07-26 18 views
17

similaire au problème décrit ici: http://rpheath.com/posts/411-how-to-use-factory-girl-with-rspecfactory_girl + rspec ne semble pas revenir sur les changements après chaque exemple

en bref (Code shorten'd):

spec_helper:

config.use_transactional_fixtures = true 
config.use_instantiated_fixtures = false 

factories.rb:

Factory.define :state do 
    f.name "NY" 
end 

dans ma spec

before(:each) do 
    @static_model = Factory(:state) # with validate uniqueness of state name 
end 

erreur:

duplicate entry name "NY" etc.


Question: Ne devrait pas Rspec base de données claire avant chaque exemple spec et donc ne pas jeter les erreurs d'entrée en double?

Répondre

40

choses que je pense au large:

  • utilisez-vous rake spec pour faire fonctionner votre testsuite: qui construit la base de données à partir de zéro (pour assurer que rien ne collait)
  • utilisez-vous, nulle part, une before (:all)? Parce que tout ce que vous créez à l'intérieur d'un before :all devrait être supprimé à nouveau dans un after :all ou il continue d'exister.
+1

Pour réitérer la suggestion de nathanvda, puisque je n'ai pas assez de karma pour voter son poste jusqu'à: Assurez-vous que tous les 'avant (: tous)' blocs d'insérer des enregistrements DB avoir un bloc 'after (: all)' correspondant pour les détruire! – dbalatero

2

Certaines causes plus possibles:

  • Il y a encore un appareil de states.yml assis autour
  • Quelqu'un a joué dans le script/test de console et a oublié de nettoyer après.
2

Vous trouverez peut-être aussi est parce que vous ne l'avez pas enveloppé la déclaration:

describe "what it should do" do 
    @static_model = Factory(:state) # with validate uniqueness of state name 
end 

J'ai découvert que était le changement qui a résolu ce problème: Why isn't factory_girl operating transactionally for me? - rows remain in database after tests

+1

C'est faux. Si vous créez l'enregistrement à partir d'un bloc before (: each) ou before (: all), vous créez l'enregistrement au moment du chargement de la suite de tests, et non lors de son exécution. Bien sûr, vous aurez l'enregistrement créé une seule fois, mais c'était par hasard. Prenez soin de cela si vous ne voulez pas vous retrouver avec un code compréhensible frustrant. – tothemario

1

J'ai eu des questions similaires à propos du type d'état de démarrage auquel on peut s'attendre lorsqu'on utilise FG et RSpec.

Alors que je trop attendre pour plus de clarté, Database Cleaner pourrait être une bonne solution: http://rubydoc.info/gems/database_cleaner/0.6.7/frames HTH - Perry

0

Lorsque vous utilisez Factory (: état) Wich est un raccourci vers Factory.create (: état), factory_girl vous renvoie un objet enregistré.

Utilisez Factory.build (: state) à la place.

0

Dude peut-être vos appareils de yaml de tests unitaires réguliers se mélangent dans votre rspec?

2

Question: Shouldn't rspec clear database before each spec example and hence not throwing duplicate entry errors?

RSpec avec Rails DatabaseCleaner ou RSpec avec use_transactional_fixtures effacera la DB tant que vous avez créé les données dans l'exemple lui-même. before :all do ... end est considéré comme étant en dehors de l'exemple, car les données restent intactes sur plusieurs exemples. Tout ce que vous créez dans before :all vous devez supprimer dans after :all.

Pour supprimer ce que vous créez automatiquement, utilisez before :each do ... end. Sachez que les mêmes données seront créées et supprimées 10 fois si vous avez 10 exemples. La différence entre before :all et before :each est mieux expliqué ici: rails rspec before all vs before each