Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RSpec and protected methods, controller spec for current_user

I might be going at this the wrong way. I'm doing the spec first, BDD/TDD and hit a bump.

I have this application_controller_spec.rb

require "spec_helper"

describe ApplicationController do
  describe "current_user" do
    it "should return nil if no one is logged in" do
      subject.current_user.should be_nil
    end
    it "should return currently logged in user" do
      hash = {user_id: "my_id"}
      subject.should_receive(:session).and_return hash
      subject.current_user.should == "my_id"
    end
  end
end

which works perfectly fine without the protected keyword.

application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery
  helper_method :current_user

  protected
  def current_user
    session[:user_id]
  end
end

with the protected enabled, I get this error msg

NoMethodError: protected method `current_user' called for #<ApplicationController:0x2a90888>

I should be able to test using the helper_method... Any suggestions?

like image 539
oma Avatar asked Mar 04 '11 14:03

oma


2 Answers

helper_method makes the method available in the views, not the controller, according to the docs.

If you really need to access the method from controller specs, you could use send:

subject.send(:current_user).should be_nil

But you might want to consider whether testing non-public methods makes sense, or if it would be better to test using view specs. Or whether the method needs to be protected in the first place. It might also be instructive to see how Devise and Authlogic implement testing for their current_user methods.

like image 133
zetetic Avatar answered Nov 12 '22 03:11

zetetic


Although it's been quite some time since the original question, maybe someone finds this useful.

You can make an anonymous subclass of the ApplicationController and expose protected methods inside it. No need for send() method.

Here is how to do it:

describe ApplicationController, type: :controller do
  controller do
    def current_user
      super
    end
  end

  ...

  it 'should return nil if no one is logged in' do
    expect(controller.current_user).to be_nil # (or whatever)
  end

end

The source is this SO answer.

like image 34
Zalom Avatar answered Nov 12 '22 03:11

Zalom