4

I have written some controller tests in a Rails app that uses Devise and Rspec. Following this guide, I've created a controller_macros.rb in the /spec/support/ directory. There is also a devise.rb file in the same directory, with:

RSpec.configure do |config|
  config.include Devise::TestHelpers, type: :controller
  config.extend ControllerMacros, :type => :controller
end

Both files are being required in the spec_helper.rb file, with this line:

Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

Now here is what is weird: this approach works fine on an OS X laptop, but fails in my Linux desktop. They both use the same RVM settings, same gemsets, same everything.

The error I get when running the tests in Linux is:

uninitialized constant ControllerMacros (NameError)

Obviously the controller_macros.rb module is failing to load in Linux. I've seen SO answers suggesting that config.extend could be changed to config.include, but that doesn't fix the problem.

Any ideas where I can look or what I can test to help isolate the issue?

I'm using Rails 4.1.8 and Rspec 3.1.7.

tala
  • 333
  • 3
  • 12
  • 1
    Discovered that explicitly autoloading the path in application.rb with `config.autoload_paths += %W(#{config.root}/spec/support)` fixes the problem - but I would love to know why one machine requires this and another does not. – tala Feb 06 '15 at 21:25
  • getting this on Mac OS X with Rails 4.2 and Rspec 3.2.0 – ballPointPenguin Feb 25 '15 at 18:56

2 Answers2

4

I struggled with this as well. Answers just weren't working for me. This is what I did (Ubuntu, Rails 4, Rspec 3):

spec/rails_helper.rb

# <snip> env stuff

require 'spec_helper'
require 'rspec/rails'
require 'devise'
require 'support/controller_macros'

# <snip> some non-devise stuff

RSpec.configure do |config|

  # <snip> some more non-devise stuff

  config.include Devise::TestHelpers, type: :controller
  config.include ControllerMacros, type: :controller
end

spec/support/controller_macros.rb

module ControllerMacros
  def login_user
    @request.env["devise.mapping"] = Devise.mappings[:user]
    user = FactoryGirl.create(:user)
    sign_in user
  end
end

students_controller.rb

require "rails_helper"

describe StudentsController, type: :controller do

  before do
    login_user
  end

  describe "GET index" do
    it "has a 200 status code" do
      get :index

      response.code.should eq("200")
    end
  end
end
charlie
  • 181
  • 13
1

I solved this by adding

require Rails.root.join("spec/support/macros/controller_macros.rb")

to the top of my spec/support/devise.rb file

ballPointPenguin
  • 1,156
  • 9
  • 9
  • Because the line Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } in spec/rails_helper.rb, spec/support/devise.rb is being loaded BEFORE spec/support/macros/controller_macros.rb . There are a number of ways to address this. – ballPointPenguin Feb 25 '15 at 20:22
  • When I try that I get an additional rspec error: ```required /Users/.../spec/support/controller_macros.rb... /Users/.../.rvm/gems/ruby-2.3.1/gems/activesupport-4.0.13/lib/active_support/dependencies.rb:229:in `require': no implicit conversion of Pathname into String (TypeError)``` – joseph.hainline Jun 16 '16 at 02:27