0
votes

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  
.  
.  
.  
1

1 Answers

1
votes

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