18

According to this from the devise wiki I should be able to use a login_user helper method in my controller tests. Accordingly I have the following within the spec directory:

#spec_helper.rb
...
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
  config.extend ControllerMacros, :type => :controller
...

and

#support/controller_macros.rb
module ControllerMacros    
  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      @user = Factory.create(:user)
      sign_in @user
    end
  end
end

however calling the helper doesn't work:

#requests/some_spec.rb
require 'spec_helper'
describe "GET /guides/edit" do
  login_user     
end

Can someone point toward where I'm going wrong. The test suite works about from this. I get a undefined local variable or method message so I guess the module isn't being included.

Rails 3.0.7 rspec 2.6.0 devise 1.3.4

backtrace

mark
  • 10,316
  • 6
  • 37
  • 58
  • Is that a typo in your some_spec.rb? `log_in` / `login_user` – Dogbert Jun 19 '11 at 16:38
  • 1
    What's the backtrace you get? – Taryn East Jun 19 '11 at 16:47
  • Hi. Have added to foot of question. – mark Jun 19 '11 at 16:52
  • hang on - that backtrace is saying it can't find you login_user method. I don't know what "controller_macros.rb" is... but how about just trying to put that straight into spec_helper.rb to see if login_user actually works... then figuring out how to include the ControllerMacros so that it can find your helper method. – Taryn East Jun 19 '11 at 17:20

4 Answers4

18

I imagine there are a couple of problems with this approach. First is that you're using request specs, not controller specs, so the login_user method is not made available by config.extend ControllerMacros, :type => :controller. Second, even if you are able to include the method it most likely won't work anyway, since the Devise test helpers are specifically written for controller/view tests, not integration tests.

Take a look at David Chelimsky's answer to this SO question, which may be of help.

Community
  • 1
  • 1
zetetic
  • 47,184
  • 10
  • 111
  • 119
4

I can't answer for sure... but the code smell for me is the "before(:each)" defined inside the helper. why don't you try:

#support/controller_macros.rb
module ControllerMacros    
  def login_user
    @request.env["devise.mapping"] = Devise.mappings[:user]
    @user = Factory.create(:user)
    sign_in @user
  end
end

and

#requests/some_spec.rb
require 'spec_helper'
describe "GET /guides/edit" do
  before(:each) do
    login_user     
  end
end

and if that fails - maybe it just can't find @request - in which case, pass it as a variable to login_user

Edit:

Looks like you might need to include the devise test helpers. The rdoc says you should have this file:

# spec/support/devise.rb
RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
end

Not sure if that differs from how you've already got it in spec_helper.rb ... looks pretty similar to me.

Taryn East
  • 27,486
  • 9
  • 86
  • 108
  • Thanks for your answer. I tried that out but it's always the missing method variable/error which seems to suggest the module isn't included at all. – mark Jun 19 '11 at 17:09
  • Hmm - sorry - I use it with Test::Unit (though I use rspec on another project), so I'm only guessing... Perhaps you could require 'devise' in spec_helper.rb ? – Taryn East Jun 19 '11 at 17:16
  • 1
    Hi Taryn. Thanks for your advice but it does look like I was confusing controller specs and request specs. – mark Jun 19 '11 at 17:34
0

Forget to confirm if your app is not confirmable. Your code should look like

module ControllerMacros
  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      user = FactoryGirl.create(:user)
      #user.confirm! # or set a confirmed_at inside the factory. Only necessary if you are using the confirmable module
      sign_in user
    end
  end
end
eayurt
  • 1,169
  • 1
  • 19
  • 42
0

I have same issue with Rails 3.0.10 rspec 2.6.0 devise 1.3.4 spork-0.9.0.rc9 on my controller specs, i have changed config. extend to config.include and its work !

Joel AZEMAR
  • 2,506
  • 25
  • 31