Last Updated: December 07, 2021
·
9.542K
· esanin

Integration Testing with rspec and devise

So we are building a Rails app and we wanted to use rspec to do some integration testing (do some testing on the requests). We created our tests in the spec/requests/ folder like this:

# encoding: UTF-8
require 'spec_helper'

describe "Links:" do
  it "should have the title 'Links'" do
    visit "/links/"
    page.should have_selector('h1', text: 'Links')
  end
end

It worked great!

$> bundle exec rspec spec/requests/links_spec.rb --order random
...
Finished in 0.2016 seconds
1 example, 0 failures

Then we added devise and it stopped working. The website now requires you to log in in order to visit that page. The rspec tests aren't doing that, so it's redirecting to the log in page where it won't find the H1 title we expect.

We looked around the internet and found two blog posts ([1] and [2]) that set us on the right track, but didn't completely solved our problem, so we had to mix them! This is how we did it:

First, let's set up FactoryGirl to mock a user. We created a factory in spec/factories/user.rb:
ruby FactoryGirl.define do factory :user do email "test@test2.com" password "testtest" password_confirmation "testtest" end end

Now we have to add helper to actually sign the user in. Following [2], we did this in spec/support/devisesupport.rb, but the `postvia_redirect` method for logging in didn't work for us, we had to use the method described in [1]:

# Module for authenticating users for request specs.
module ValidUserRequestHelper
  # Signs in a valid user uwing the page.drive.post method
  def sign_in_as_valid_user_driver
       @user ||= FactoryGirl.create :user
      page.driver.post user_session_path, :user => {:email => @user.email, :password => @user.password}
  end
end

We have to configure spec/spec_helper.rb to use this helper.

RSpec.configure do |config|
  [...]
  config.include ValidUserRequestHelper, :type => :request
end

Now we can use the method sign_in_as_valid_user_driver in our specs:

# encoding: UTF-8
require 'spec_helper'

describe "Links:" do
  it "should have the title 'Links'" do
    sign_in_as_valid_user_driver
    visit "/links/"
    page.should have_selector('h1', text: 'Links')
  end
end

Of course there will be several tests, so we shouldn't be repeating the call in each one:

# encoding: UTF-8
require 'spec_helper'

describe "Links:" do

  before do
    sign_in_as_valid_user_driver
  end

  it "should have the title 'Links'" do
    visit "/links/"
    page.should have_selector('h1', text: 'Links')
  end
end