Mocks aren't working with RSpec and Devise

2019-05-12 18:22发布

问题:

I'm working on a Rails 3 web app at the moment with RSpec 2 and we're using Devise for authentication. One (and soon many) of our controllers require the user to be logged in. I know Devise provides the sign_in test helper, but can it be used with an RSpec or Mocha mock object?

I originally tried @user = mock_model(User) where user is the Devise class. This wouldn't work with sign_in :user, @user as get 'index' would redirect to the sign in form.

Does anyone have any experience testing with Devise and can help?

回答1:

We had a similar problem, but using Factory Girl. We solved it like so:

In spec_helper.rb:

config.include Devise::TestHelpers, :type => :controller

In the controller spec (just a wrapper method):

def login_user(user)
    sign_in user
end

Then in each method you require, you can do:

login_user(Factory(:user))

... where you have defined a user object in factories.rb. Not sure if this will work with mocks though.



回答2:

A mock is never going to work. When you say sign in, the user is stored in session (basically, the user class and its id). When you access the controller, another user object is retrieved based on the stored data. The best way to solve the problem is using something that persists the object, like Factory Girl.



回答3:

I hit the same issue. I'm doing the following for now:

before(:each) do
  # sign_in mock_user
  request.env['warden'] = mock(Warden, :authenticate => mock_user,
                                       :authenticate! => mock_user)
end


回答4:

I've created an issue for this here: https://github.com/plataformatec/devise/issues#issue/928 Go vote!



回答5:

None of them worked for me (MRI 1.9.3-preview1, rails 3.0.1.rc5).

this is the solution i found : http://blog.joshmcarthur.com/post/6407481655/integration-tests-with-devise-and-rspec