0
votes

Here is my little problem that makes me feel stupid. I'm testing my rails application with RSpec and I also have devise controller helper (grabbed from the Devise wiki, note user default parameter):

module ControllerMacros
  module ControllerHelpers
    def sign_in(user=mock_model(User))
      if user.nil?
        request.env['warden'].stub(:authenticate!).
          and_throw(:warden, {:scope => :user})
        controller.stub :current_user => nil
      else
        # Lots of user.stub here
        controller.stub :current_user => user
      end
    end
  end

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

Now when I use sign_in in one context of my controller test everything works fine:

context "Authorized access" do
    before(:each) do
      mocked_user = mock_model(User)
      mocked_user.stub(:is?).with(:admin).and_return(true)
      sign_in(mocked_user)
      # some checks 
    end
end

But in another context (in the same spec) I'm getting "wrong number of arguments (2 for 1)":

context "Unauthorized access" do
 before(:each) do
   sign_in(nil)
 end

# test cases
end

And it's rather confusing for me, because I'm passing only one(nil) argument. I'll be glad to hear any suggestions, because these two calls look the same for me. Maybe I`m missing something.

UPDATE:

  1. Rails 3.1.0
  2. ruby 1.9.3p0 (2011-10-30 revision 33570)
  3. RSpec 2.7.1

UPDATE 2(error example):

 Failure/Error: sign_in(nil)
   ArgumentError:
   wrong number of arguments (2 for 1)
   # ./spec/support/controller_macros.rb:5:in `sign_in'
   # ./spec/controllers/forum/topics_controller_spec.rb:93:in `block (3 levels) in <top (required)>'
1
Can you post the full error message, please? - d11wtq
From the devise wiki - "At the time of writing no gem version of rspec-mocks doesn't support throw parameters, so you'll need to use the git repository in the meantime (alongside rspec and rspec-rails 2.8.0.rc1)." RSpec 2.8.0 was released the other day - Bangline

1 Answers

2
votes

The error will be coming from the line

request.env['warden'].stub(:authenticate!).and_throw(:warden, {:scope => :user})

RSpec versions lower than 2.8 did not support parameters for and_throw. Update the Gemfile to use RSpec 2.8.0 and let me know how you get on.

I remember I used a simpler method for controller tests

before do
  controller.stub(:authenticate!).and_return(mock_model('user'))
end

That way you are bypassing Devise altogether which is well tested