53

I'm using Rails 5, and Devise 3.5.1.

Going through a nice (older) book about creating/testing an API, which uses Devise authentication. It was written before Rails 5, so I chose not to use the new api-only version.

Here's my test...

#/spec/controllers/api/v1/users_controller_spec.rb    

require 'rails_helper'

describe Api::V1::UsersController, :type => :controller do
    before(:each) { request.headers['Accept'] = "application/vnd.marketplace.v1" }
    describe "GET #show" do
        before(:each) do
            @user = FactoryGirl.create :user
            get :show, params: {id: @user.id}, format: :json
        end
        it "returns the information about a reporter on a hash" do
            user_response = JSON.parse(response.body, symbolize_names: true)
            expect(user_response[:email]).to eql @user.email
        end
        it { should respond_with 200 }
    end
end

And here's a completely unexpected RSpec error

Devise::MissingWarden:
       Devise could not find the `Warden::Proxy` instance on your request environment.
       Make sure that your application is loading Devise and Warden as expected and that the `Warden::Manager` middleware is present in your middleware stack.
       If you are seeing this on one of your tests, ensure that your tests are either executing the Rails middleware stack or that your tests are using the `Devise::Test::ControllerHelpers` module to inject the `request.env['warden']` object for you.

So I go here - http://www.rubydoc.info/gems/devise/Devise/Test/ControllerHelpers

and tried this -> include Devise::Test::ControllerHelpers

which didn't help because the file controller_helpers.rb is nowhere in my project

What did I miss here?

Thanks

1
  • According to this answer, you cannot use Warden/Devise in a controller test (ActionController::TestCase) because it is Rack middleware and the Rack middleware is not loaded for controller tests. stackoverflow.com/questions/13420923/…
    – Chloe
    Commented Sep 19, 2018 at 22:08

3 Answers 3

114

You could add the following to your rails_helper:

RSpec.configure do |config|
  config.include Devise::Test::ControllerHelpers, type: :controller
end

This will include Devise::Test::ControllerHelpers module in all :controller specs.

2
  • OK that makes sense. Thanks sir. The type: :controller is there just to save memory when RSpec is running other types of tests?
    – dwilbank
    Commented Jul 17, 2016 at 15:53
  • 3
    Devise::Test::ControllerHelpers is intended to be used only in controller tests, so I think some of other specs might be broken if it's included in all of them. That's why we need to specify type: :controller.
    – lest
    Commented Jul 17, 2016 at 15:55
11

In the spec_helper.rb add:

config.include Devise::Test::ControllerHelpers, :type => :controller
0
1

MiniTest, Rails 4

This works for vanilla Rails 4 MiniTest

test\controllers\users_controller_test.rb
require 'test_helper'

class UsersControllerTest < ActionController::TestCase
  include Warden::Test::Helpers
  include Devise::Test::ControllerHelpers

  setup do
    # https://github.com/plataformatec/devise/wiki/How-To:-Test-with-Capybara
    # @user = users(:admin)
    # sign_in @user
  end

  teardown do
    Warden.test_reset!
  end

  test "login as admin" do
    @user = users :admin
    sign_in @user
    get :dashboard
    assert_redirected_to admin_dashboard_path
  end

end

Not the answer you're looking for? Browse other questions tagged or ask your own question.