Search code examples
ruby-on-railsrspecrails-enginesspork

Spork & Rails 3.1 engine: helpers are not reloaded


I'm developing a Rails 3.1 engine and want to test it. I use RSpec for this, and everything works nicely, but when trying to use Spork, I have the problem that my helpers are not correctly reloaded.

I read a lot about a similar problem with models, and I came up with the following possible fix:

# my_engine/spec/spec_helper.rb

ActiveSupport::Dependencies.clear
ActiveRecord::Base.instantiate_observers

Dir[File.join(File.dirname(__FILE__), '..', 'app', 'helpers', '*.rb')].each do |file|
  require file
end

# my_engine/spec/dummy/config/environments/test.rb
Dummy::Application.configure do
  # ...
  config.cache_classes = !(ENV['DRB'] == 'true') # Ensure that classes aren't cached when using Spork.
  # ...
end

This works as far as it definitely is reloading ever helper file (I added a breakpoint to check this), but the changes are not reflected within the tests, only a restart of Spork does. Maybe it's because helpers are modules, and the tests don't rely on the module but on the classes that implement the modules, so the modules are properly reloaded but not properly mixed in??

At the time being, I'm just putting all intitializer code into the each_run block:

# Configure Rails Environment
ENV["RAILS_ENV"] = "test"

require File.expand_path("../dummy/config/environment.rb", __FILE__)
require 'rspec/rails'

Rails.backtrace_cleaner.remove_silencers!

# Load support files
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }

RSpec.configure do |config|
  config.use_transactional_fixtures = true

  config.treat_symbols_as_metadata_keys_with_true_values = true
  config.filter_run :focus => true
  config.run_all_when_everything_filtered = true
end

Solution

  • I have done a lot of research about this topic, and I've written about in these two blog posts:

    Regarding especially to my question above: I can imagine that it didn't work because I didn't require 'rspec/autorun' in the Spork.prefork block, but I'm not completely sure.

    Here's the spec_helper.rb for my current engine (which successfully reloads everything as needed):

    require 'rubygems'
    require 'spork'
    
    Spork.prefork do
      ENV["RAILS_ENV"] ||= 'test'
      require File.expand_path("../dummy/config/environment", __FILE__)
      require 'rspec/rails'
      require 'rspec/autorun'
    
      Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
    
      RSpec.configure do |config|
        config.use_transactional_fixtures = true
        config.fixture_path = "#{::Rails.root}/spec/fixtures"
        config.infer_base_class_for_anonymous_controllers = false
        config.treat_symbols_as_metadata_keys_with_true_values = true
        config.filter_run :focus => true
        config.run_all_when_everything_filtered = true
      end
    end
    
    Spork.each_run do
      # This code will be run each time you run your specs.
    end