Question

Declaring a class for (fast) testing purposes is great:

require 'fast_helper'
require 'site_search'

class Post; end # This allows not to load the whole Rails env

describe SiteSearch do
  it "searches on posts" do
    Post.stub_chain(:scoped, :by_term).with("ruby").and_return ["post1", "post2"]
    SiteSearch.by_term("ruby").should == ["post1", "post2"]
  end
end

The problem with it is that it seems to break autoloading of rails models when the whole suite of specs is run.

The models aren't loaded anymore when the class gets declared before.

There are 4 ways of injecting the unloaded dependencies:

  1. Declare the class (as in example here)
  2. Set/remove const
  3. Stub a wrapper method
  4. Actually load them

I only want to use the 1st one.

The question: keeping the same specs structure, how can I tell rails to actually load the models even though the class is already declared?

Was it helpful?

Solution

In order for your empty class preemption trick to work, you must have set your app config.cache_classes = false, hence eager loading is not happening unless you call

Rails.application.eager_load!

When running the whole test suite you need to make sure classes preload, then empty redefinition should have no effect.

Now the question is how you control that it is run only if the full test suite is called. The honest answer is I don't know, but you can surely control it from the environment. Somewhere in your rspec helpers you initialize rails, update it to something like:

ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
Rails.application.eager_load! unless ENV["FORCE_EAGER_LOAD"].blank?

and then call rspec on full suite as:

FORCE_EAGER_LOAD=t rspec
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top