Reputation: 2846
I am using Rails4 and devise. While writing controller specs, I came across this code:
user = double(@user)
request.env['warden'].stub :authenticate! => user
allow(controller).to receive(:current_user) { user }
... here.
It works. The controller specs I wrote that require authentication pass appropriately.
I've read some web entries about how a stub works, and I think I get it. Seems fast and adequate for my needs.
Even though the above code uses the RSpec double
method, I still get this depreciation warning:
Using
stub
from rspec-mocks' old:should
syntax without explicitly enabling the syntax is deprecated. Use the new:expect
syntax or explicitly enable:should
instead. Called from /Users/perry_mac/rails_projects/mymri/spec/controllers/steps_controller_spec.rb:14:in `block (2 levels) in '.
Which puzzles me since I am using the "new :expect syntax." So I am left with a vague unease about this otherwise working code snippet. For instance, it is not immediately clear how I could use it to write a test that makes use of two users logging in and ensuring each is seeing only their appropriately scoped search results. Is there a more suitable way to stub a session to check controllers that make use of authentication?
And... why does the above work, but something like this does not?:
before(:each) {
email = "[email protected]"
password= "password"
@user = FactoryGirl.create(:user, email: email, password: password)
session[:user_id] = @user.id
.
.
.
Upvotes: 0
Views: 414
Reputation: 2846
Apparently, all I needed was:
@request.env["devise.mapping"] = Devise.mappings[:user]
sign_in @user
according to this which says:
There are two things that are important to keep in mind:
1) These helpers are not going to work for integration tests driven by Capybara or Webrat. They are meant to be used with functional tests only. Instead, fill in the form or explicitly set the user in session;
2) If you are testing Devise internal controllers or a controller that inherits from Devise's, you need to tell Devise which mapping should be used before a request. This is necessary because Devise gets this information from the router, but since functional tests do not pass through the router, it needs to be told explicitly. For example, if you are testing the user scope, simply do:
@request.env["devise.mapping"] = Devise.mappings[:user]
get :new
Upvotes: 1