Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rspec controller spec on namespaced controller finds the global controller with same name

I have a weird issue when creating a controller spec for a namespaced controller when there also is a global controller with the same name.

The controller names are HomeController and Backend::HomeController.

Note that I have not yet created the file app/controllers/backend/home_controller.rb, only the global controller exists app/controllers/home_controller.rb

Therefore I expect the test to explode with errors, but it does not. It passes, all green and happy.

My spec looks like this

#spec/controllers/backend/home_controller_spec.rb
require 'rails_helper'

RSpec.describe Backend::HomeController, type: :controller do
  before do
    user = FactoryGirl.create(:user)
    allow(controller).to receive(:authenticate_user!).and_return(true)
    allow(controller).to receive(:current_user).and_return(user)
  end
  describe "GET #index" do
    it "returns http success" do
      get :index
      expect(response).to have_http_status(:success)
    end
  end

end

However if I change the name in my global HomeController to something else, e.g NotMyHomeController the test fails with errors saying

Unable to autoload constant HomeController, expected app/controllers/home_controller.rb to define it

Which makes me suspect that Rspec doesn't bother with the "Backend" part in the Rspec.describe function.

Am I doing something wrong or am I missing some other vital part? IMHO, this spec shouldn't pass (to paraphrase Gandalf).

I'm using Rails 4.2.6, Rspec-Rails 3.4.2

Update

As Max pointed out, this is probably not at Rspec issue but instead something with Rails autoloading.

However i tried just typing

Backend::HomeController

In the Rails console, but there I get the expected error

NameError: uninitialized constant Backend::HomeController

And according to the Rails guide, both the console and the test suite autoloads. However I think I'm on the right track here.

like image 843
Jacob Rastad Avatar asked Oct 19 '22 12:10

Jacob Rastad


1 Answers

I had this same problem before - you can read about the whole issue here:

Object.const_get and Rails - cutting off parent module names

but the meat of the answer comes from this answer from user Apneadiving:

Be aware that there are vicious cases in Rails development mode. In order to gain speed, the strict minimum is loaded. Then Rails looks for classes definitions when needed.

But this sometimes fails big time example, when you have say ::User already loaded, and then look for ::Admin::User. Rails would not look for it, it will think ::User does the trick.

This can be solved using require_dependency statements in your code.

like image 162
dax Avatar answered Oct 27 '22 23:10

dax