ruby-on-railstest-environments

autoload specific module during testing in Rails


i noticed my controller test started growing too large, so i moved some stubbing methods into a separate module.

i put it in test/lib/my_module.rb

module MyModule
  def mymethod
  end
end

so my controller test in test/controllers/my_controller.rb now looks this way:

class MyControllerTest < ActionController::TestCase
  include MyModule
  def test_something
  end
end

i then tried making rails autoload path "test/lib" during tests only. for this, i added following lines in config/environments/test.rb

config.autoload_paths += ["#{config.root}/test/lib"]
config.eager_load_paths += ["#{config.root}/test/lib"]

but when i run my tests with "RAILS_ENV=test bundle exec rake test", it throws:

rake aborted!
NameError: uninitialized constant MyControllerTest::MyModule

if i put same two lines in config/application.rb, everything works well. but i dont want to load this module f.ex. in production.

so why does it happen and how do i fix it? and what is Rails best practice for keeping test-specific code?


Solution

  • I place helpers under test/support/*.rb and include it:

    test/test_helper.rb:

    # some code here
    
    Dir[Rails.root.join('test', 'support', '*.rb')].each { |f| require f }
    
    class ActiveSupport::TestCase
      include Warden::Test::Helpers
      include Auth # <- here is a helper for login\logout users in the test env
      # some code here
    

    It's normal practice for share modules with a test specs.