Rspec/Rails 4, access current_user from Rspec.feature spec?
TL;DR
Don't use controller helpers in feature specs -- in BDD, you want the feature specs to do everything through the browser DSL (like Capybara). In your case, it would be better to write a separate helper method for signing in with Capybara (example below).
Explanation
You want your feature spec to be from the perspective of the user. The user doesn't care how the controller creates a user session, and neither should your feature spec. It should stay within the domain of the spec type.
In your case, the better solution would be to write a another helper method (specifically for :feature
specs) that signs the user in through Capybara methods, so that your entire feature test occurs from the same flow/perspective. Here's a generic helper method that I use in all my apps:
# spec/support/feature_helpers.rb
module FeatureHelpers
def sign_in
@user = FactoryGirl.create(:user)
visit "/"
click_link "Sign In"
fill_in "user_email", with: @user.email
fill_in "user_password", with: @user.password
click_button "Sign in"
end
end
RSpec.configure do |config|
config.include FeatureHelpers, :type => :feature
end
Then, your spec would look something like this:
require "rails_helper"
RSpec.feature "Carpool Invitations", :type => :feature do
let!(:carpool) { FactoryGirl.create(:carpool)}
# you could still create a user here if you wanted
scenario "User sends a new carpool invite" do
sign_in
visit new_carpool_invite_path(carpool)
fill_in "invite[to_user]", :with => "matthewalexander108@gmail.com"
click_button "Send Invitation"
expect(page).to have_text("Invitation was successfully sent!")
end
end
RSpec + Capybara + Devise: current_user?
The devise wiki is correct for how to test while shortcutting logins, and no you can't just set current_user
in your test code (nor can you access it since it's only set inside the request). Generally assume the error is in your usage of a gem, rather than a widely used and highly tested gem being defective.
With the description you've given there could be any number of reasons for it not actually logging in the user however the two most likely culprits are
Do you actually have multiple scopes configured in Devise? or should it just be
login_as(admin, :scope => :user)
# equivalent to just login_as(admin)Is
puma
running your tests in single mode, or clustered mode? (You may need to disable the silencing of puma output rspec-rails does by default -https://github.com/rspec/rspec-rails/blob/95f4522c0549a32de59c19eb9b5f9a72126a9eb6/lib/rspec/rails/example/system_example_group.rb#L72 - to see that in the test output) If it's not in single mode then the app is being run in a separate process than the tests which means Devise can't actually shortcircuit the login, and you need to fix the puma config.
Rspec. How to test current_user method
I'm assuming you're wrapping the current_user
method from Devise (you're calling super
) and you're using the devise test helper sign_in
. It needs the scope or a user object as its first argument. Change your before
in your test to:
before do
sign_in :user, user
end
or just:
before do
sign_in user
end
The default scope in Devise is :user
and you don't need to tell sign_in
unless it's different.
RSpec: how to stub inherited method current_user (w/o Devise)?
Also works
user = create(:user) #FactoryBot
allow(controller).to receive(:current_user).and_return(user)
RSpec accessing application_controller methods such as 'current_user'
rspec-rails gives you a controller
method for use in controller examples. So:
controller.stub!(:current_user).with(:foos).and_return(foos)
ought to work.
Related Topics
Micropost's Comments on Users Page (Ruby on Rails)
Ruby Compare Two Strings Similarity Percentage
Fail VS. Raise in Ruby:Should We Really Believe the Style Guide
Factorygirl Association Model Trouble: "Systemstackerror: Stack Level Too Deep"
How to Parse JSON Request Body in Sinatra Just Once and Expose It to All Routes
How to Test Code Coverage for Rails Erb Templates
How to Compare a String Against Multiple Other Strings
How to Use Dot Syntax for Ruby Hash
Suppressing the Output of a Command Run Using 'System' Method While Running It in a Ruby Script
Custom Ruby Gem in Gemfile on Heroku
Do Fixtures Trigger Model Callbacks
How to Catch Errno::Econnreset Class in "Case When"
How to Change "Devise: Password Reset Instruction Email's Subject"
Getting Webpage Content with Ruby -- I'm Having Troubles
How to Deal with Not Knowing What Exceptions Can Be Raised by a Library Method in Ruby
Creating a Capistrano Task That Performs Different Tasks Based on Role
Rails Fixtures Not Loading with Rspec
Why Is "Wsdl" Namespace Interjected into Action Name When Using Savon for Ruby Soap Communication