J'essaie d'utiliser factory_girl pour créer une usine "utilisateur" (avec RSpec) mais il ne semble pas fonctionner de manière transactionnelle et échoue apparemment à cause des données restantes des tests précédents dans la base de données de test.
Factory.define :user do |user|
user.name "Joe Blow"
user.email "joe@blow.com"
user.password 'password'
user.password_confirmation 'password'
end
@user = Factory.create(:user)
L'exécution de la première série de tests se passe bien :
spec spec/
...
Finished in 2.758806 seconds
60 examples, 0 failures, 11 pending
Tout est bon et conforme aux attentes, mais je recommence les tests :
spec spec/
...
/Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/validations.rb:1102:in `save_without_dirty!': Validation failed: Email has already been taken (ActiveRecord::RecordInvalid)
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/dirty.rb:87:in `save_without_transactions!'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:200:in `save!'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:182:in `transaction'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:200:in `save!'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.8/lib/active_record/transactions.rb:200:in `save!'
from /Library/Ruby/Gems/1.8/gems/factory_girl-1.2.3/lib/factory_girl/proxy/create.rb:6:in `result'
from /Library/Ruby/Gems/1.8/gems/factory_girl-1.2.3/lib/factory_girl/factory.rb:316:in `run'
from /Library/Ruby/Gems/1.8/gems/factory_girl-1.2.3/lib/factory_girl/factory.rb:260:in `create'
from /Users/petenixey/Rails_apps/resample/spec/controllers/users_controller_spec.rb:7
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_group_methods.rb:183:in `module_eval'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_group_methods.rb:183:in `subclass'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_group_methods.rb:55:in `describe'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/example/example_group_factory.rb:31:in `create_example_group'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/dsl/main.rb:28:in `describe'
from /Users/petenixey/Rails_apps/resample/spec/controllers/users_controller_spec.rb:3
from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:147:in `load_without_new_constant_marking'
from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:147:in `load'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/example_group_runner.rb:15:in `load_files'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/example_group_runner.rb:14:in `each'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/example_group_runner.rb:14:in `load_files'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/options.rb:133:in `run_examples'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/lib/spec/runner/command_line.rb:9:in `run'
from /Library/Ruby/Gems/1.8/gems/rspec-1.3.0/bin/spec:5
from /usr/bin/spec:19:in `load'
from /usr/bin/spec:19
Tentative de correction - utiliser Factory.sequence
Comme j'ai une contrainte d'unicité sur mon champ email, j'ai essayé de résoudre le problème en utilisant la méthode de séquence de factory_girl :
Factory.define :user do |user|
user.name "Joe Blow"
user.sequence(:email) {|n| "joe#{n}@blow.com" }
user.password 'password'
user.password_confirmation 'password'
end
J'ai ensuite couru
rake db:test:prepare
spec spec/
.. # running the tests once executes fine
spec spec/
.. # running them the second time produces the same set of errors as before
Les utilisateurs semblent rester dans la base de données
Si je regarde la base de données /db/test.sqlite3, il semble que la ligne de l'utilisateur de test ne soit pas supprimée de la base de données entre les tests. Je pensais que ces tests étaient censés être transactionnels, mais il semble que ce ne soit pas le cas pour moi.
Cela expliquerait pourquoi le test se déroule correctement la première fois (et si j'efface la base de données) mais échoue la deuxième fois.
Quelqu'un peut-il m'expliquer ce que je dois changer pour que les tests s'exécutent de manière transactionnelle ?
Merci.