How to Stub out Warden/Devise with Rspec in Capybara test
Warden comes with built in test helpers. It allows you to login without having to use the UI in your cucumber tests. Just add the files below into your project.
# features/support/warden.rb
Warden.test_mode!
World Warden::Test::Helpers
After { Warden.test_reset! }
# features/step_definitions/user_steps.rb
Given /^I am logged in as a user$/ do
@current_user = User.create!(:username => 'user', :password => 'password')
login_as(@current_user, :scope => :user)
end
Use Wardens.test_mode! with Capybara
How to sign users in and out for testing with Rspec + Devise + FactoryGirl
Your setup is totally OK. One thing as @Greg Tarsa said is that you may want to perform such kind of tests at feature level. Another thing from me is that one should use one single spec to test one single thing e.g. it should be single (or several) expect
in it
block. But it's not strict rule - it's up to you to decide.
And I made some refactoring of your setup with previous tips and feature-style syntax. Maybe it would be useful:
background do
@user = build(:user)
login_as(@user)
visit root_path
end
scenario "links persist in both states" do
expect(page).to have_link('Site Title', href: root_path, count: 1)
end
scenario "links dropped out after login" do
expect(page).not_to have_link('Login', href: new_user_session_path)
expect(page).not_to have_link('Join', href: signup_path)
end
scenario "links added after login" do
expect(page).to have_link('Add Item', href: new_item_path)
expect(page).to have_link('My Items', href: myitems_path)
end
RSpec with devise - only the first test is logged in
Use before(:each)
, not before(:context)
:
before(:each) do # <-- !!!!
# ..
login_as(@user, :scope => :user)
end
after(:each) do
Warden.test_reset!
end
Your problem is that the before(:context)
is only running once - i.e. before the first test runs, whereas the after(:each)
is running for each test.
Therefore after the first test runs, you've signed out and are not signing back in.
Rails 3 with Devise and rspec: Warden test helpers unreliable
The absolute easiest thing to do is just use the sign_in form in your before :each
block. You need the test helpers in Controller specs, because it's isolated from devise. You don't have that problem in an integration test.
In RSpec Capybara tests how can you stub your own app's API?
As you mentioned this is not something you should really be doing in a feature test. Normally you would configure the data, in your test, using fixtures or factories so that your API is actually run and returns the data you are expecting.
If, however, you insist on continuing with your current plan, the best solution (since it doesn't modify your app code, and runs closest to the idea of feature tests) is a programmable proxy like puffing-billy
- https://github.com/oesmith/puffing-billy. It's like WebMock but for requests initiated from the browser instead of internal to your app, and is designed to integrate nicely to the available Capybara drivers.
How to sign in without warden callback on rspec (request spec)
You can pass run_callbacks: false
option to Warden's login_as
helper:
login_as(user, run_callbacks: false)
Related Topics
Post Redirect Get Pattern in Rails
Accessing a Has_One Associations' Attributes
Ruby How to Merge Two CSV Files with Slightly Different Headers
How to Set Up the Recipient Id in Public Activity
Rails Routing - Custom Routes for Resources
How Are Respond_To and Respond_To_Missing Different
Importing CSV Data into Rails App, Using Something Other Then the Association "Id"
Building Gem, Executable Not Found
Fast-Stemmer Installation Problems
Exec the Cd Command in a Ruby Script
Selenium2 Webdriver Ruby => How Click on a Hidden Link
Why Does Hash#Select and Hash#Reject Pass a Key to a Unary Block
Ruby Converting Utc to User's Time Zone