Dave G
Dave G

Reputation: 4386

Rspec failing with load_missing_constant when classes live in subdirectories and are subclassed

I'm having some troubles running a bunch of RSpec tests due to something I suspect is related to autoloading. Here is the error:

/usr/share/ruby-rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.1.4/lib/active_support/dependencies.rb:490:in `load_missing_constant': Expected /var/lib/jenkins/.../portfolios/base_manage_controller.rb to define Portfolios::BaseManageController (LoadError)
from /usr/share/ruby-rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.1.4/lib/active_support/dependencies.rb:181:in `block in const_missing'
from /usr/share/ruby-rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.1.4/lib/active_support/dependencies.rb:179:in `each'
from /usr/share/ruby-rvm/gems/ruby-1.9.2-p320/gems/activesupport-3.1.4/lib/active_support/dependencies.rb:179:in `const_missing'
from /usr/share/ruby-rvm/gems/ruby-1.9.2-p320@global/gems/rake-0.9.2.2/lib/rake/ext/module.rb:36:in `const_missing'
from /var/lib/jenkins/jobs/.../app/controllers/portfolios/customize_controller.rb:1:in `<top (required)>'

Here is the header of the file:

class Portfolios::BaseManageController < ApplicationController

And it lives in app/controllers/portfolios/base_manage_controller.rb

And its subclass:

class Portfolios::CustomizeController < Portfolios::BaseManageController

And it lives in app/controllers/portfolios/customize_controller.rb

Finally here are a bunch of autoloads:

config.autoload_paths += Dir["#{config.root}/lib",  "#{config.root}/lib/**/"]
config.autoload_paths += %W(#{config.root}/app/models/statistics)

#Any test/dev specific load paths
if not Rails.env.production?
  config.autoload_paths += %W(#{config.root}/spec/support)
  config.autoload_paths += %W(#{config.root}/spec/support/builders)
  config.autoload_paths += %W(#{config.root}/spec/support/modules)
  config.autoload_paths += %W(#{config.root}/spec/support/utils)
end

Any help would be much appreciated!

Upvotes: 11

Views: 5084

Answers (4)

ihoka
ihoka

Reputation: 147

This error sometimes occurs when there is an exception raised when the class is defined. In this case, a runtime error may be occurring when attempting to define the class found in base_manage_controller.rb.

To verify this is the case, try stripping out everything from base_manage_controller.rb, except the class declaration:

class Portfolios::BaseManageController < ApplicationController
end

It should result in the specs running, but failing.

To find the runtime error, put everything back into the class, and load it from script/console, by calling Portfolios::BaseManageController. That will attempt to dynamically load the class, and raise the exception that prevents your class from being defined.

Upvotes: 2

shivashankar
shivashankar

Reputation: 1177

Following solution will help you

create spec in following path for app/controllers/portfolios/base_manage_controller.rb spec/controllers/portfolios/base_manage_controller_spec.rb

The spec content should be like this

describe Portfolios::BaseManageController do
 -----
end

You can apply the same logic for app/controllers/portfolios/customize_controller.rb

Upvotes: 0

danpickett
danpickett

Reputation: 2046

there is a collision in your autoload path because of the existence of a file with the same name at /var/lib/jenkins/.../portfolios/base_manage_controller.rb

You need to either modify your load path so app/controllers comes up earlier in the list or the file specified at the path above should be renamed or removed.

Upvotes: 0

chifung7
chifung7

Reputation: 2621

It looks like that Portfolios is not defined when rspec is loading Portfolios::BaseManageController. Where did you define Portfolios? If it's defined as a module or class somewhere in a separate file, you need to require this file first.

Upvotes: 0

Related Questions