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