How to stub ApplicationController method in request spec How to stub ApplicationController method in request spec ruby-on-rails ruby-on-rails

How to stub ApplicationController method in request spec


skalee seems to have provided the correct answer in the comment.

If the method you're trying to stub is an instance method (most likely) and not a class method then you need use:

ApplicationController.any_instance.stub(:current_user)


Here are a couple of examples of the basic form.

controller.stub(:action_name).and_raise([some error])controller.stub(:action_name).and_return([some value])

In your particular case, I believe the proper form would be:

controller.stub(:current_user).and_return([your user object/id])

Here's a full working example from a project I work on:

describe PortalsController do  it "if an ActionController::InvalidAuthenticityToken is raised the user should be redirected to login" do    controller.stub(:index).and_raise(ActionController::InvalidAuthenticityToken)    get :index    flash[:notice].should eql("Your session has expired.")    response.should redirect_to(portals_path)  endend

To explain my full example, basically what this does is verify that, when an ActionController::InvalidAuthenticityToken error is raised anywhere in the app, that a flash message appears, and the user is redirected to the portals_controller#index action. You can use these forms to stub out and return specific values, test an instance of a given error being raised, etc. There are several .stub(:action_name).and_[do_something_interesting]() methods available to you.


Update (after you added your code): per my comment, change your code so it reads:

require 'spec_helper'describe "Login" do   before(:each) do      @mock_controller = mock("ApplicationController")       @mock_controller.stub(:current_user).and_return(User.first)   end  it "logs in" do    visit '/'    page.should have_content("Hey there user!")  endend


This works for me and gives me a @current_user variable to use in tests.

I have a helper that looks like this:

def bypass_authentication  current_user = FactoryGirl.create(:user)  ApplicationController.send(:alias_method, :old_current_user, :current_user)  ApplicationController.send(:define_method, :current_user) do     current_user  end  @current_user = current_userenddef restore_authentication  ApplicationController.send(:alias_method, :current_user, :old_current_user)end

And then in my request specs, I call:

before(:each){bypass_authentication}after(:each){restore_authentication}