2011-05-06 12 views
13

Tengo un problema con el servidor de prueba de Spork.Problema de spork y cache_classes con rspec, factory_girl y datamapper

Si configuro config.cache_classes = false en config/environments/test.rb, las especificaciones comienzan a generar errores.

Failure/Error: task = Factory(:something, :foo => @foo, :bar => @bar) 
    DataMapper::ImmutableError: 
     Immutable resource cannot be modified 

Esta es mi spec_helper.rb:

require 'spork' 

Spork.prefork do 
    if ENV['CODE_COVERAGE'] == '1' 
    require 'simplecov' 
    SimpleCov.start 'rails' 
    end 

    ENV["RAILS_ENV"] ||= 'test' 
    require File.expand_path("../../config/environment", __FILE__) 
    require 'rspec/rails' 
    require 'webmock/rspec' 
    require 'factory_girl' 

    Dir[Rails.root.join("spec/controllers/shared/*.rb")].each { |f| require f } 
    Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } 

    RSpec.configure do |config| 
    config.mock_with :mocha 
    config.include Rails.application.routes.url_helpers 
    config.include UrlHelper 

    config.before(:each) do 
     repository(:default) do 
     transaction = DataMapper::Transaction.new(repository) 
     transaction.begin 
     repository.adapter.push_transaction(transaction) 
     end 
    end 

    config.after(:each) do 
     repository(:default).adapter.pop_transaction.try(:rollback) 
    end 

    end 
end 

# This code will be run each time you run your specs. 
Spork.each_run do 
    # reload factories 
    Factory.definition_file_paths = Dir[File.join(Rails.root, "spec", "factories")] 
    Factory.find_definitions 

    DatabaseCleaner.strategy = :truncation 
    DatabaseCleaner.clean 
    LoggedEvent.all.destroy! 

end 

Cuando tengo config.cache_classes = true, entonces todo funciona bien, pero no me ilegible, modelos, clases de controladores, por lo que don' Veamos un punto en el uso de spork en este caso.

He intentado añadir a spec_helper.rb algo como esto, cuando la memoria caché es cierto:

Spork.each_run do 
    Dir.glob("#{Rails.root}/app/models/*.rb").sort.each { |file| load file } 
end 

Pero no me gusta esta solución.

Respuesta

20

Sólo añadir:

ActiveSupport::Dependencies.clear 

al final del bloque prefork. esto se encargará de limpiar los modelos.

Además, desea mover esa configuración de configuración rspec a Spork.each_run, lo mismo ocurre con la necesidad de compatibilidad de especificaciones y archivos compartidos.

Esto funciona, utilizo esta configuración en 2 proyectos sin problemas.

+3

Espere, ¿así que 'ActiveSupport :: Dependencies.clear' pertenece a prefork o each_run? He visto historias conflictivas Ninguno de los dos parece funcionar, y ambos causan problemas de carga: "xxxx esperado para definir xxxx". Además, ¿es solo 'ActiveSupport :: Dependencies.clear' que resuelve el problema? ¿O es necesario junto con el ejemplo each_run en la pregunta original? –

+0

No sé por qué, pero mi proyecto de repente comenzó a hacer esto, sin ningún motivo aparente. Terminé poniendo Dependencies.clear en mi Spork.each_run, y funcionó para mí. No tengo mi Rspec.config en each_run, solo: FactoryGirl.reload y ActiveSupport :: Dependencies.clear. Espero que ayude. –

+0

ActiveSupport :: Dependencies.clear debe agregarse al final de la preforma, no cada_run – Ran

8

Try ActionDispatch :: Reloader

Además de establecer config.cache_classes = false en config/environments/test.rb, la siguiente parece tener DataMapper y Spork juegan muy bien para nuestro equipo:

Spork.each_run do 

    # Routes 
    MyApp::Application.reload_routes! 

    if Spork.using_spork? 
    # Reload all app files 
    ActionDispatch::Reloader.cleanup! 
    ActionDispatch::Reloader.prepare! 

    # All factories 
    FactoryGirl.reload 
    end 

end 
+0

Agradable. No esperaba, pero esto pareció solucionar mis problemas con Mongoid y Spork. Toda la otra documentación sobre el tema ([Spork.trap_method Jujitsu] (https://github.com/sporkrb/spork/wiki/Spork.trap_method-Jujitsu) y 'ActiveSupport :: Dependencies.clear') no funcionó en todas. Incluso pude deshacerme de mi trampa extra en 'Rails :: Mongoid.load_models'. –

+1

Este enfoque realmente incluye ActiveSupport :: Dependencies.clear y más. Llamando a ActionDispatch :: Reloader.cleanup! ¡y preparar! es exactamente lo que recarga! lo hace en la consola de rieles. +1 –

0

Hola quería compartir lo que me ayudó corriendo la prueba de nuevo.
Resulta que tuve que agregar el truco shared_connection ya que spork se quejaba de la pérdida de conexión.
Después de esto tuve que cambiar la línea dependency.clear al final del bloque ya que estaba almacenando en caché mis modelos.

Spork.each_run do 
    # ActiveSupport::Dependencies.clear # <-- moved this line at end of block as suggested by @solnic 
    ActiveRecord::Base.instantiate_observers 
    MyApp::Application.reload_routes! 
    FactoryGirl.reload 

    class ActiveRecord::Base 
    mattr_accessor :shared_connection 
    @@shared_connection = nil 

    def self.connection 
     @@shared_connection || retrieve_connection 
    end 
    end 
    ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection 

    ActiveSupport::Dependencies.clear # <-- line moved here 

end if Spork.using_spork? 
Cuestiones relacionadas