How to stub ApplicationController method in request specification

I need to drown out the response of the current_user method in the Rspec / capybara request specification. The method is defined in ApplicationController and uses helper_method. The method should simply return the user id. As part of the test, I would like this method to return the same user ID every time.

Alternatively, I could fix my problem by setting session[:user_id] to spec (which returns current_user ) ... but this also doesn't work.

Are any of these options possible?

Edit:

Here is what I got (it doesn't work, it just runs the regular current_user method).

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

Also does not work:

 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!") end end 
+54
ruby ruby-on-rails rspec capybara
Sep 16 '11 at 18:36
source share
5 answers

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

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

ApplicationController.any_instance.stub(:current_user)

+57
Aug 29 2018-12-21T00:
source share

Here are some 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 that the correct form is:

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

Here is a complete working example of a project I'm working 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) end end 

To explain my complete example, this basically means that when an ActionController::InvalidAuthenticityToken error ActionController::InvalidAuthenticityToken , a flash message appears anywhere in the application and the user is redirected to the action portals_controller#index . You can use these forms to display and return specific values, check an instance of a given error, etc. There are several .stub(:action_name).and_[do_something_interesting]() methods available.




Refresh (after adding the code): for my comment, change your code so that 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!") end end 
+13
Sep 16 '11 at 19:00
source share

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

I have an assistant 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_user end def restore_authentication ApplicationController.send(:alias_method, :current_user, :old_current_user) end 

And then in my specification requests, I call:

 before(:each){bypass_authentication} after(:each){restore_authentication} 
+3
Oct 14 '12 at 1:01
source share

For those who might need to drown out the application controller method that installs ivar (and was drowned out by endless wanking about why you shouldn't do this) here, a method that works with Rspec flavor around October 2013.

 before(:each) do campaign = Campaign.create! ApplicationController.any_instance.stub(:load_campaign_singleton) controller.instance_eval{@campaign = campaign} @campaign = campaign end 

it locks the method to do nothing, and installs ivar on the rspec controller instance and makes it available for testing like @campaign.

+2
Nov 07 '13 at 2:14
source share

None of the answers provided worked for me. As in the original post @ matt-fordam, I have a request specification, not a controller specification. The test simply displays the view without starting the controller.

I solved this by imposing a method on the view as described in this other SO post

 view.stub(:current_user).and_return(etc) 
+1
Nov 18 '13 at 4:32
source share



All Articles