NameError: uninitialized constant when trying to execute rails tests
ruby, ruby-2.0, ruby-on-rails, ruby-on-rails-3, testunit
Solution
Finally I found the reason why all my tests failed with an error. I was referencing to a constant declared in the `Availability` concern using `Availabiliy::` , instead of using `Business::`. Also, my tests were not in sync with the current code, which made finding the bug a lot more difficult than it should. Replacing all the references to `Availability` with `Business` solved the problem. The lesson here is: keep always application and testing code in sync.
Thank you to Lichtamberg for all his kind support.
Problem
In a Rails 3.2.13 app I'm writing right now I have a model called `Business`. As this model was getting fatter and fatter, I decided to split it up in two, extracting all code related to availability into a Rails concern named `Availability`, stored at `models/concerns/business` ``` class Business module Availability extend ActiveSupport::Concern AVAILABILITY_OPEN = 1 AVAILABILITY_CLOSED = -1 AVAILABILITY_COMPLETE = -2 ... ``` As concerns are not enabled in Rails by default, I've put the following line in `config/application.rb` in order to autoload them: ``` config.autoload_paths += %W(#{config.root}/app/models/concerns) ``` The problem is that, after the split, all my tests have stopped working, returning a `NameError: uninitialized constant Availability` error. I suppose I need to require this concern somehow in my tests, but I haven't managed to do it yet, and I also don't understand why this concern is needed even in tests which doesn't make use of it. The following is the stack trace returned after running the tests: ``` NameError: uninitialized constant Availability (erb):9:in `<main>' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/erb.rb:849:in `eval' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/erb.rb:849:in `result' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures/file.rb:51:in `render' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures/file.rb:43:in `rows' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures/file.rb:29:in `each' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:670:in `block (2 levels) in read_fixture_files' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures/file.rb:20:in `open' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:669:in `block in read_fixture_files' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:668:in `each' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:668:in `read_fixture_files' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:548:in `initialize' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:482:in `new' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:482:in `block (2 levels) in create_fixtures' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:479:in `map' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:479:in `block in create_fixtures' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:232:in `disable_referential_integrity' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:476:in `create_fixtures' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:895:in `load_fixtures' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activerecord-3.2.13/lib/active_record/fixtures.rb:849:in `setup_fixtures' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:407:in `_run__871072887135343583__setup__3260066542044458782__callbacks' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:405:in `__run_callback' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:385:in `_run_setup_callbacks' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:81:in `run_callbacks' /home/sergio/.rvm/gems/ruby-2.0.0-p247/gems/activesupport-3.2.13/lib/active_support/testing/setup_and_teardown.rb:35:in `run' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:919:in `block in _run_suite' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:912:in `map' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:912:in `_run_suite' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:657:in `block in _run_suites' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:655:in `each' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:655:in `_run_suites' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:867:in `_run_anything' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1060:in `run_tests' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1047:in `block in _run' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1046:in `each' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1046:in `_run' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/minitest/unit.rb:1035:in `run' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:21:in `run' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:774:in `run' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:366:in `block (2 levels) in autorun' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:27:in `run_once' /home/sergio/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/test/unit.rb:365:in `block in autorun' ``` UPDATE This is an excerpt of the class `Business`, which includes the `Availability` concern: ``` class Business < ActiveRecord::Base include Availability include EmailVirtualAttribute include TelephoneVirtualAttribute belongs_to :place has_many :businesses_users has_many :users, :through => :businesses_users, :uniq => true has_many :customers, :inverse_of => :business, :dependent => :destroy has_many :emails, :as => :contactable, :class_name => 'Email' has_many :telephones, :as => :contactable, :class_name => 'Telephone' ... ``` The development/test configs are the standard ones, no changes have been made test.rb ``` Rendezvous::Application.configure do # Settings specified here will take precedence over those in config/application.rb # The test environment is used exclusively to run your application's # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! config.cache_classes = true # Configure static asset server for tests with Cache-Control for performance config.serve_static_assets = true config.static_cache_control = "public, max-age=3600" # Log error messages when you accidentally call methods on nil config.whiny_nils = true # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false # Raise exceptions instead of rendering exception templates config.action_dispatch.show_exceptions = false # Disable request forgery protection in test environment config.action_controller.allow_forgery_protection = false # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test # Raise exception on mass assignment protection for Active Record models config.active_record.mass_assignment_sanitizer = :strict # Print deprecation notices to the stderr config.active_support.deprecation = :stderr end ``` development.rb ``` Rendezvous::Application.configure do # Settings specified here will take precedence over those in config/application.rb # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false # Log error messages when you accidentally call methods on nil. config.whiny_nils = true # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false # Don't care if the mailer can't send config.action_mailer.raise_delivery_errors = false # Print deprecation notices to the Rails logger config.active_support.deprecation = :log # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin # Raise exception on mass assignment protection for Active Record models config.active_record.mass_assignment_sanitizer = :strict # Log the query plan for queries taking more than this (works # with SQLite, MySQL, and PostgreSQL) config.active_record.auto_explain_threshold_in_seconds = 0.5 # Do not compress assets config.assets.compress = false # Expands the lines which load the assets config.assets.debug = true end ``` UPDATE 2 It seems that the errors that happen when executing the tests are caused by the fixtures. If I comment the `fixtures :all` loading on `test_helper.rb` and create a simple test that just asserts true, this test pass, but it doesn't when the fixtures are loaded.