Devise: Testing controllers and requests that need authentication with rspec2
Montag, 04. April 2011, 01:07 Uhr | roberto@vasquez-angel.de |Imagine you have been happily writing your controller test and then, you have to add authentication to your application using devise.
Assume you have a posts controller with following test:
require 'spec_helper' describe PostsController do def mock_post(stubs={}) @mock_post ||= mock_model(Post, stubs).as_null_object end describe "GET index" do it "assigns all posts as @posts" do Post.stub(:all) { [mock_post] } get :index assigns(:posts).should eq([mock_post]) end end describe "GET show" do it "assigns the requested post as @post" do Post.stub(:find).with("37") { mock_post } get :show, :id => "37" assigns(:post).should be(mock_post) end end end
First, you’ll have to add the Devise TestHelpers. Add a new file spec/support/devise.rb
:
RSpec.configure do |config| config.include Devise::TestHelpers, :type => :controller end
You’ll need a factory for the admin. I use factory girl. Add the admin factory to Rails.root/spec/factories.rb
:
Factory.define(:admin) do |admin| admin.email "admin@example.com" admin.password "foobar" end
Then you throw all your controller tests into a new describe block, that signins in your admin before each test:
describe PostsController do describe "as a signed in admin" do before(:each) do admin = Factory(:admin) sign_in admin end def mock_post(stubs={}) @mock_post ||= mock_model(Post, stubs).as_null_object end describe "GET index" do it "assigns all posts as @posts" do Post.stub(:all) { [mock_post] } get :index assigns(:posts).should eq([mock_post]) end end describe "GET show" do it "assigns the requested post as @post" do Post.stub(:find).with("37") { mock_post } get :show, :id => "37" assigns(:post).should be(mock_post) end end end end
Customize the request specs. Before:
require 'spec_helper' describe "NewsItems" do describe "GET /news_items" do it "works! (now write some real specs)" do # Run the generator again with the --webrat flag if you want to use webrat methods/matchers get news_items_path response.status.should be(200) end end end
and with devise integration:
require 'spec_helper' describe "NewsItems" do context "as logged in admin" do before(:each) do admin = Factory(:admin) get new_admin_session_path fill_in :email, :with => admin.email fill_in :password, :with => admin.password click_button end describe "GET /news_items" do it "works! (now write some real specs)" do # Run the generator again with the --webrat flag if you want to use webrat methods/matchers get news_items_path response.status.should be(200) end end end end