Estoy tratando de usar factory_girl para crear una fábrica de "usuario" (con RSpec) sin embargo, no parece estar operando transaccionalmente y aparentemente está fallando debido a datos remanentes de pruebas previas en el base de datos de prueba.¿Por qué factory_girl no funciona transaccionalmente para mí? - las filas permanecen en la base de datos después de las pruebas
Factory.define :user do |user|
user.name "Joe Blow"
user.email "[email protected]"
user.password 'password'
user.password_confirmation 'password'
end
@user = Factory.create(:user)
Ejecución de la primera serie de pruebas está muy bien:
spec spec/
...
Finished in 2.758806 seconds
60 examples, 0 failures, 11 pending
Todo bien y como se esperaba, sin embargo ejecutar las pruebas de nuevo: intento
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
Fix - utilizar Factory.sequence
Como tengo una singularidad const Raint en mi campo de correo electrónico que intentó solucionar el problema utilizando el método de secuencia 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
entonces me encontré con
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
usuarios parecen permanecer en la base de datos
Si Cuando miro la base de datos /db/test.sqlite3, parece que la fila para el usuario de prueba no se está retirando de la base de datos entre las pruebas. Pensé que se suponía que estas pruebas serían transaccionales, pero no parecen ser así para mí.
Esto explicaría por qué la prueba se ejecuta correctamente la primera vez (y si borro la base de datos) pero falla por segunda vez.
¿Alguien puede explicar lo que debería cambiar para asegurarse de que las pruebas se ejecutan de forma transaccional?
¿Puedo sugerir que se eliminen las menciones de factory-girl en la pregunta y la etiqueta? Dado que el problema central realmente se trata de crear registros en el bloque equivocado. Lo mismo puede suceder si se crea un registro mediante la llamada create() incorporada. – lulalala