Rails + Devise and Rspec

So I tried using Devise on a project and ran into an issue with the default generated controller specs.

PlansController POST create with invalid params re-renders the 'new' template
Failure/Error: response.should render_template("new")
expecting <"new"> but rendering with <"">
# ./plans_controller_spec.rb:73:in `block (4 levels) in <top (required)>'

PlansController PUT update with invalid params re-renders the 'edit' template
Failure/Error: response.should render_template("edit")
expecting <"edit"> but rendering with <"">
# ./plans_controller_spec.rb:117:in `block (4 levels) in <top (required)>'

The problem is that my application is requiring a valid user here, so the controller is redirecting rather than rendering what is expected.

If you look you’ll find helpful advise on the Devise wiki about how to resolve this issue for your controller specs.

I’m using FactoryGirl, so this is the solution I went with:

$ cat spec/support/controller_macros.rb

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

In spec/spec_helper.rb:

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

Now what about those integration tests, so-called request specs in rspec parlance. It turns out you need a means of logging in for those specs too.

1) Plans GET /plans works! (now write some real specs)
Failure/Error: response.status.should be(200)

expected #<Fixnum:401> => 200
got #<Fixnum:605> => 302

After quite a bit of googling I came across the following which seems to work great.


$ cat spec/support/request_macros.rb

module RequestMacros
  def login(user)
    page.driver.post user_session_path, 
      :user => {:email => user.email, :password => user.password}
  end
end

In spec/spec_helper.rb:

RSpec.configure do |config|
...
  config.include RequestMacros, :type => :request
end
Advertisements
This entry was posted in rails and tagged , . Bookmark the permalink.

One Response to Rails + Devise and Rspec

  1. Pingback: Cant sign in user in Rspec test ( devise gem )

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s