Spork and cache_classes problem with rspec, factory_girl and datamapper
I've got a problem with Spork test server.
If I set config.cache_classes = false in config/environments/test.rb then specs start to rasie errors.
Failure/Error: task = Factory(:something, :foo => @foo, :bar => @bar)
DataMapper::ImmutableError:
Immutable resource cannot be modified
This is my 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
e开发者_高级运维nd
# 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
When I have config.cache_classes = true, then everything works well, but It not reload me a models, controllers classes, so I don't see a point in using spork in this case.
I tried to add to spec_helper.rb something like this, when cache is true:
Spork.each_run do
Dir.glob("#{Rails.root}/app/models/*.rb").sort.each { |file| load file }
end
But I don't like this solution.
Just add:
ActiveSupport::Dependencies.clear
to the end of the prefork block. this will take care of clearing the models.
Also, you want to move that rspec configure inclusions to Spork.each_run, same goes with requiring spec support and shared files.
This works, I use this setup in 2 projects w/o any troubles.
Try ActionDispatch::Reloader
In addition to setting config.cache_classes = false
in config/environments/test.rb
, the following seems to make DataMapper and Spork play nicely for our team:
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
Hi I wanted to share what helped me running test again.
It turns out I had to add the shared_connection
trick as spork was complaining about connection lost.
After this I had to shift the dependency.clear
line at at the end of the block as it was caching my models.
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?
精彩评论