My Beautiful Controller Spec
Today I spent a few hours refining my controller rspec pattern. I’m really pleased with it.
This controller:class AssignmentsController < ApplicationController
def index
if params[:person_id]
@person = Person.find params[:person_id]
@assignments = @person.assignments
@title = "Assignments for #{@person}"
elsif params[:course_id]
@course = Course.find params[:course_id]
@assignments = @course.assignments
@title = "Assignments for #{@course}"
else
@assignments = Assignment.find :all
@title = "All Assignments"
end
@ical_url = url_for({ :format => :ics }.merge(params))
@rss_url = url_for({ :format => :rss }.merge(params))
end
endrequire File.dirname(__FILE__) + '/../spec_helper'
describe AssignmentsController do
describe 'index action GET request with' do
describe 'no parameters' do
before(:each) do get 'index' end
it 'should successfully respond' do response.should be_success end
it 'should assign a title' do assigns[:title].should == 'All Assignments' end
it 'should assign assignments' do assigns[:assignments].should == Assignment.find(:all) end
end
describe 'a valid person_id' do
before(:each) do get 'index', :person_id => (@person = test_person) end
it 'should successfully respond' do response.should be_success end
it 'should assign a title' do assigns[:title].should == "Assignments for #{@person}" end
it 'should assign assignments' do assigns[:assignments].should == @person.assignments end
end
describe 'a valid course_id' do
before(:each) do get 'index', :course_id => (@course = test_course) end
it 'should successfully respond' do response.should be_success end
it 'should assign a title' do assigns[:title].should == "Assignments for #{@course}" end
it 'should assign assignments' do assigns[:assignments].should == @course.assignments end
end
describe 'any valid parameters' do
before(:each) do get 'index' end
it 'should assign a rss_url' do assigns[:rss_url].should == 'http://test.host/assignments.rss' end
it 'should assign an ical_url' do assigns[:ical_url].should == 'http://test.host/assignments.ics' end
end
end
endLiberal use of nesting, alignment, and inline assignments, hooray.
Beautiful specs mean I’m that much more likely to actually write them…
Can it get any better?
Validation Assertions
I like to test my validations. While I don’t really care to test the underlying code that runs the validations (I trust the Rails team to make sure they work as advertised) I do like the reassurance that I didn’t screw up. So, I’ve written this small plugin to help me test my validations.
It works simply. In one of your models you’ve got a validation like this:class User < ActiveRecord::Base
validates_presence_of :name
validates_length_of :name, :in => 4..26
validates_uniqueness_of :name
endclass UserTest < Test::Unit::TestCase
# Assert that a User's name must exist for validations to pass.
def test_validates_presence_of_name
assert_validates_presence_of User, :name
end
# Assert that a User's name must be at least 4 characters in length for
# validations to pass.
def test_validates_minimium_length_of_name
assert_validates_minimum_length_of User, :name, 4
end
# Assert that a User's name must be less than 26 characters in length for
# validations to pass.
def test_validates_maximum_length_of_name
assert_validates_maximum_length_of User, :name, 26
end
# Assert that a User's name must be unique for validations to pass.
def test_validates_uniqueness_of_name
assert_validates_uniqueness_of User, :name
end
endThat’s it. Now you can rest easy know that your validations are really, really, really in place.
To install the plugin:script/plugin install http://validation-assertions.googlecode.com/svn/trunk/validation_assertions/