Speeding up you tests with Spork is very common when developping Rails applications.
What Spork do is preloading your application in a server and copies a fork of that server whenever you run tests.
It avoids reloading all the rails stack !! That is great !!!
But the problem I ran into is that I wanted to be able to
- reload my application files
- and keep cache_classes = true
That is why I like ruby and rails (and great coders there ! ). What I simply did :
- Reading and understanding the rails initialize process (especially these lines engine.rb and finisher.rb )
- Adding these small pieces of code in my prefork block with Spork trap method
- trap eager loading in my prefork block like below
require 'rails/application' # Use of https://github.com/sporkrb/spork/wiki/Spork.trap_method-Jujutsu Spork.trap_method(Rails::Application, :reload_routes!) Spork.trap_method(Rails::Application::RoutesReloader, :reload!) require 'rails/mongoid' Spork.trap_class_method(Rails::Mongoid, :load_models) # Prevent main application to eager_load in the prefork block (do not load files in autoload_paths) Spork.trap_method(Rails::Application, :eager_load!) # Below this line it is too late... require File.expand_path("../../config/environment", __FILE__) # Load all railties files Rails.application.railties.all { |r| r.eager_load! }
My own benefits : specs runs faster than setting cache_classes = false
You need small explanation of what I’ve done !
Spork.trap_method(Rails::Application, :eager_load!) require File.expand_path("../../config/environment", __FILE__) Rails.application.railties.all { |r| r.eager_load! }
First, we prevent Rails::Application to loads files in the application autoload_paths such as app/models, app/controllers etc …
Spork.trap_method(Rails::Application, :eager_load!)
Second, we load the rails stack :
require File.expand_path("../../config/environment", __FILE__)
Last, we eager load all the engines :
Rails.application.railties.all { |r| r.eager_load! }
Doing that we can make change in our models and avoid restarting spork.
Why don’t I just set cache_classes to false ?
Because the ActiveSupport::Dependencies.mechanism is set to :require and not :load
All application files are required and not just loaded (spork required them just after forking, not before).
This trick could resolve some inconsistencies in your application (such as already defined constant and else …)

